angular - Angular 7 Reactive Form Builder,自定义交叉验证器不起作用
问题描述
这是我的 HTML:
<mat-form-field>
<input matInput type="number" min="0" max="100" step="1" placeholder="Allowed Attendance (%)" required [formControl]="allowed" name="allowed_attendance">
<mat-error *ngIf="allowed.invalid">Value must be 0-100</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput type="number" min="0" max="100" step="1" placeholder="Fined Attendance (%)" required [formControl]="fined" name="fined_attendance">
<mat-error *ngIf="fined.invalid">This value must be less than allowed attendance</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput required [formControl]="ldo_form_fill_up" placeholder="Applicable Until" [matDatepicker]="picker" name="ldo_form_fill_up">
<mat-datepicker-toggle #toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
<mat-error *ngIf="ldo_form_fill_up.invalid">A valid date is required</mat-error>
</mat-form-field>
<mat-form-field *ngIf="ldo_form_fill_up.valid">
<input matInput required [formControl]="ldo_payment" placeholder="Payable Until" [matDatepicker]="picker2" name="ldo_payment">
<mat-datepicker-toggle #toggle2 matSuffix [for]="picker2"></mat-datepicker-toggle>
<mat-datepicker #picker2></mat-datepicker>
<mat-error *ngIf="ldo_payment.invalid">This date must be greater than the above</mat-error>
</mat-form-field>
以下是 getter 表单控件:
get ldo_form_fill_up() {
return this.form.get('ldo_form_fill_up');
}
get ldo_payment() {
return this.form.get('ldo_payment');
}
get allowed() {
return this.form.get('allowed_attendance');
}
get fined() {
return this.form.get('fined_attendance');
}
这是表单构建器:
this.form = fb.group({
allowed_attendance: fb.control(70, [Validators.required, Validators.min(0), Validators.max(100)]),
fined_attendance: fb.control(60, [Validators.required, Validators.min(0), Validators.max(100)]),
ldo_form_fill_up: fb.control('', Validators.required),
ldo_payment: fb.control('', Validators.required),
}, {
validators: customRangeValidator
});
这是自定义验证器:
export function customRangeValidator(group: FormGroup) {
const date1 = group.controls.ldo_form_fill_up;
const date2 = group.controls.ldo_payment;
const attd1 = group.controls.allowed_attendance;
const attd2 = group.controls.fined_attendance;
if (date1.value >= date2.value) {
date2.setErrors({
customRangeValidator: true
});
}
if (attd2.value >= attd1.value) {
attd2.setErrors({
customRangeValidator: true
});
}
return null;
}
我需要什么:fined_attendance < allowed_attendance
和ldo_payment > ldo_form_fill_up
到底是怎么回事:
- 输入
70
_allowed_attendance
- 输入
60
_fined_attendance
- 没有错误
fined_attendance
(没关系)。 - 更改
allowed_attendance
为50
。 - 显示错误
fined_attendance
(也可以)。 - 再换
allowed_attendance
一次70
。 - 仍然显示错误。(不行)。
- 但清除并重新输入
60
,fined_attendance
错误消失了!
所以,我面临着显示在的麻烦step 7
。我在做什么错?
解决方案
我认为您只关心设置错误而不是清除它们。
在 else 条件下,您还应该清除它们。就是这样:
import { Component } from '@angular/core';
import { FormBuilder, Validators, FormGroup } from '@angular/forms';
/** @title Simple form field */
@Component({
selector: 'form-field-overview-example',
templateUrl: 'form-field-overview-example.html',
styleUrls: ['form-field-overview-example.css'],
})
export class FormFieldOverviewExample {
form: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit() {
this.form = this.fb.group({
allowed_attendance: this.fb.control(70, [Validators.required, Validators.min(0), Validators.max(100)]),
fined_attendance: this.fb.control(60, [Validators.required, Validators.min(0), Validators.max(100)]),
ldo_form_fill_up: this.fb.control('', Validators.required),
ldo_payment: this.fb.control('', Validators.required),
}, { validators: customRangeValidator });
}
submit() {
console.log(this.form.value);
}
get ldo_form_fill_up() {
return this.form.get('ldo_form_fill_up');
}
get ldo_payment() {
return this.form.get('ldo_payment');
}
get allowed() {
return this.form.get('allowed_attendance');
}
get fined() {
return this.form.get('fined_attendance');
}
}
export function customRangeValidator(group: FormGroup) {
console.log('Called');
const { ldo_form_fill_up, ldo_payment, allowed_attendance, fined_attendance } = group.controls;
if (fined_attendance.value >= allowed_attendance.value) {
fined_attendance.setErrors({ customRangeValidator: true });
} else {
fined_attendance.setErrors(null);
}
if (ldo_form_fill_up.value >= ldo_payment.value) {
ldo_payment.setErrors({ customRangeValidator: true });
} else {
ldo_payment.setErrors(null);
}
return null;
}
此外,在您的模板中,不要使用[formGroup]
为什么不简单地使用formGroupName
. 像这样的东西:
<form [formGroup]="form">
<mat-form-field>
<input matInput type="number" min="0" max="100" step="1" placeholder="Allowed Attendance (%)" required formControlName="allowed_attendance" name="allowed_attendance">
<mat-error *ngIf="allowed.invalid">Value must be 0-100</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput type="number" min="0" max="100" step="1" placeholder="Fined Attendance (%)" required formControlName="fined_attendance" name="fined_attendance">
<mat-error *ngIf="fined.invalid">This value must be less than allowed attendance</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput required formControlName="ldo_form_fill_up" placeholder="Applicable Until" [matDatepicker]="picker" name="ldo_form_fill_up">
<mat-datepicker-toggle #toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
<mat-error *ngIf="ldo_form_fill_up.invalid">A valid date is required</mat-error>
</mat-form-field>
<mat-form-field *ngIf="ldo_form_fill_up.valid">
<input matInput required formControlName="ldo_payment" placeholder="Payable Until" [matDatepicker]="picker2" name="ldo_payment">
<mat-datepicker-toggle #toggle2 matSuffix [for]="picker2"></mat-datepicker-toggle>
<mat-datepicker #picker2></mat-datepicker>
<mat-error *ngIf="ldo_payment.invalid">This date must be greater than the above</mat-error>
</mat-form-field>
<br>
<button
[disabled]="form.invalid"
mat-raised-button
color="primary"
(click)="submit()">
Primary
</button>
</form>
这是您参考的工作示例 StackBlitz。
推荐阅读
- ubuntu - 在 ubuntu 上恢复 clion 默认设置
- javascript - 如何使用用户输入修改数组(用 html 中的表格显示)
- php - Symfony POST Value Id 转换为实体
- django - Проблема с файлом wsgi.py(wsgi.py 文件的问题)
- flutter - 如何获取 sqflite 使用的 db 文件?
- html - 外部 CSS 字体系列未在浏览器中显示
- python - Python - 创建一个检查列表列表中的新元素的函数
- php - 如何从 Lumen 连接到 Firebird 数据库?
- python - 在 Python for 循环中使用 %s
- python - 标签和列表视图未显示在小部件上