Angular 反应式表单至少验证字段不为空且 'lifecycle' 验证器
Angular reactive forms validate at least on field is not empty and 'lifecycle' of validator
我想验证至少一个字段 不是 空的表单 - 至少一个字段已归档。我创建了自定义验证器:
import { FormControl, FormGroup, ValidationErrors, ValidatorFn } from "@angular/forms";
export const pfkValidator: ValidatorFn = (abstractControl: AbstractControl): ValidationErrors | null => {
let fg = (abstractControl as FormGroup);
let isValid = false;
Object.keys(fg.controls).forEach(
field => {
const ctrl = fg.get(field);
if (ctrl instanceof FormControl) {
console.log('ctrl value', ctrl.value);
if (ctrl.value) {
isValid = true;
}
}
});
if (isValid) return { 'valid': true }
return null;
}
这是初始化表单的方式:
ngOnInit(): void {
this.form = this.fb.group({
Field1: [null],
Field2: [null],
Field3: [null],
Field4: [null],
Field5: [null],
Field6: [null],
Field7: [null],
Field8: [null],
Field9: [false],
Field10: [false],
}, { validators: pfkValidator });
}
问题是当表单加载时,每个字段的验证都会被激活,这需要相当长的时间。我的表单有 10 个字段,我在控制台中记录了 10x10 个输入。
这是预期的行为吗?
下面是您的实现,它在控制台中显示了 121 条日志
然而,在下面使用 FormArrays
的实现中,我尝试减少 运行 操作以避免循环 Demo using FormArrays。现在控制台最初仅显示 14 条日志,每次编辑 1 条日志。您甚至可以添加 updateOn: 'blur'
以进一步提高性能
export const pfkValidator: ValidatorFn = (
abstractControl: AbstractControl
): ValidationErrors | null => {
console.log("ctrl value", abstractControl.value.join(""));
if (abstractControl.value.join("") !== "") {
return { atLeastOne: false };
}
return null;
};
这可以像下面这样实现
export class AppComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {}
get fields() {
return this.form.get("fields") as FormArray;
}
ngOnInit(): void {
this.form = this.fb.group({
fields: this.fb.array(
[null, null, null, null, null, null, null, null, false, false],
{ validators: [pfkValidator] }
)
});
}
}
并在 html
<form [formGroup]='form'>
<ng-container formArrayName='fields'>
<input *ngFor="let control of fields.controls; let i = index" [formControlName]="i">
</ng-container>
</form>
我想验证至少一个字段 不是 空的表单 - 至少一个字段已归档。我创建了自定义验证器:
import { FormControl, FormGroup, ValidationErrors, ValidatorFn } from "@angular/forms";
export const pfkValidator: ValidatorFn = (abstractControl: AbstractControl): ValidationErrors | null => {
let fg = (abstractControl as FormGroup);
let isValid = false;
Object.keys(fg.controls).forEach(
field => {
const ctrl = fg.get(field);
if (ctrl instanceof FormControl) {
console.log('ctrl value', ctrl.value);
if (ctrl.value) {
isValid = true;
}
}
});
if (isValid) return { 'valid': true }
return null;
}
这是初始化表单的方式:
ngOnInit(): void {
this.form = this.fb.group({
Field1: [null],
Field2: [null],
Field3: [null],
Field4: [null],
Field5: [null],
Field6: [null],
Field7: [null],
Field8: [null],
Field9: [false],
Field10: [false],
}, { validators: pfkValidator });
}
问题是当表单加载时,每个字段的验证都会被激活,这需要相当长的时间。我的表单有 10 个字段,我在控制台中记录了 10x10 个输入。
这是预期的行为吗?
下面是您的实现,它在控制台中显示了 121 条日志
然而,在下面使用 FormArrays
的实现中,我尝试减少 运行 操作以避免循环 Demo using FormArrays。现在控制台最初仅显示 14 条日志,每次编辑 1 条日志。您甚至可以添加 updateOn: 'blur'
以进一步提高性能
export const pfkValidator: ValidatorFn = (
abstractControl: AbstractControl
): ValidationErrors | null => {
console.log("ctrl value", abstractControl.value.join(""));
if (abstractControl.value.join("") !== "") {
return { atLeastOne: false };
}
return null;
};
这可以像下面这样实现
export class AppComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {}
get fields() {
return this.form.get("fields") as FormArray;
}
ngOnInit(): void {
this.form = this.fb.group({
fields: this.fb.array(
[null, null, null, null, null, null, null, null, false, false],
{ validators: [pfkValidator] }
)
});
}
}
并在 html
<form [formGroup]='form'>
<ng-container formArrayName='fields'>
<input *ngFor="let control of fields.controls; let i = index" [formControlName]="i">
</ng-container>
</form>