【发布时间】:2020-08-26 10:03:03
【问题描述】:
在我的 FormGroup 中有一个 FormArray,其中包含 n 个 FormControl,每个 FormControl 都附有一个电子邮件验证器。
我希望我的 FormArray 能够知道任何 FormControl 是否有电子邮件验证错误,如果是,则 FormError 错误属性应设置为 {email: true}。
为此,我编写了一个应用于我的 FormArray 的自定义验证器。但是,当从 FormArray 添加或删除 FormControl 元素时,此验证器似乎没有正确触发。
this.form = this.formBuilder.group({
alertContacts: this.formBuilder.array(this.alertData.alertContacts, [Validators.required, alertContactsArrayValidator]),
});
此表单数组由一个子组件控制,该子组件具有对作为实例化时的输入传递给它的 formArray 的引用。子组件中给formArray加值的方法是
pushToFormcontrol(value: any) {
if(!this.fArray.value.includes(value)){
if(this.usesAutocomplete){
if(this.autocompleteData.some(el => el === value)) {
this.fArray.push(this.formBuilder.control(value));
this.filterAutocomplete();
this.clearInput();
}
} else {
this.fArray.push(this.formBuilder.control(value, [Validators.email]));
this.clearInput();
}
}
this.fArray.markAsDirty();
}
我的 FormArray 的自定义验证器是
export function alertContactsArrayValidator(): ValidatorFn {
return (formArray: FormArray): { [key: string]: any } | null => {
console.log(formArray);
let hasEmailErrors = false;
let formControls = formArray.controls;
console.log(formControls);
formControls.forEach(control => {
let controlErrors: ValidationErrors = control.errors;
console.log("Current control errors: ", controlErrors);
Object.keys(controlErrors).forEach(key => {
if (key === 'email') {
hasEmailErrors = true;
console.log("key has email");
}
});
});
return hasEmailErrors ? {email: true} : null;
};
}
如果我在浏览器中调试我的代码,我可以看到外部的 alertContactsArrayValidator 函数被单步执行,但返回的内部函数从未被激活。我也从来没有看到任何控制台日志。
编辑
经过进一步的实验,我发现了一些有趣的东西。如果我修改我的 FormArray 以便我插入一个空数组而不是我的 this.alertData.alertContacts (它是一个字符串数组),那么验证器就可以完美地工作。我开始认为这是我创建 FormArray 的方式的问题。
this.form = this.formBuilder.group({
alertContacts: this.formBuilder.array([], [Validators.required, alertContactsArrayValidator]), //An empty array works fine
});
如果我想用其中已经存在的元素来实例化我的 FormArray,我是否应该以不同于将数组作为 this.formBuilder.array() 方法的第一个参数传递的方式来执行它?
【问题讨论】:
标签: angular validation angular-reactive-forms