Angular 为 FormArray 提供除空数组以外的任何内容时自定义验证器中断
Angular custom validator breaks when providing FormArray with anything other than empty array
我有一个与我的 FormArray 一起使用的自定义验证器,只要 FormArray 的输入是 []
,验证器就可以正常工作。但是,如果我为 FormArray 提供 string[]
或 FormControl[]
,验证器将破坏整个 angular 应用程序并导致无限循环错误。
我真的不确定是什么导致了这种情况发生。我需要能够用元素实例化 FormArray,所以我需要它才能工作。
起初我认为问题是由于我将 string[]
传递给 FormArray 而不是 FormControl[]
,但即使在将数组映射到 FormControls 数组之后我得到同样的问题。
this.alertData.alertContacts
只是一个电子邮件字符串数组。
FormGroup 实例化 - 有效
this.form = this.formBuilder.group({
alertContacts: this.formBuilder.array([], [Validators.required, alertContactsArrayValidator()]),
});
FormGroup 实例化 - 损坏
this.form = this.formBuilder.group({
alertContacts: this.formBuilder.array(this.alertData.alertContacts, [Validators.required, alertContactsArrayValidator()]),
});
FormGroup 实例化 - 损坏
this.form = this.formBuilder.group({
alertContacts: this.formBuilder.array(this.alertData.alertContacts.map(x => new FormControl(x)), [Validators.required, alertContactsArrayValidator()]),
});
自定义验证器
export function alertContactsArrayValidator(): ValidatorFn {
return (c: AbstractControl): { [key: string]: any } | null => {
let formArray = <FormArray>c;
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;
};
}
您需要检查 control.errors 是否为空。
formControls.forEach(control => {
let controlErrors: ValidationErrors = control.errors;
if (controlErrors){ //<---this "if"
Object.keys(controlErrors).forEach(key => {
if (key === 'email') {
hasEmailErrors = true;
console.log("key has email");
}
});
}
});
你也可以更简单
formControls.forEach(control => {
if (control.errors && control.errors.email){
hasEmailErrors = true;
console.log("key has email");
}
});
甚至
formControls.forEach(control => {
hasEmailErrors = hasEmailErrors ||
(control.errors && control.errors.email)
}
});
注意:我想你想要
this.form = this.formBuilder.group({
alertContacts: this.formBuilder.array(this.alertData.alertContacts
.map(x => new FormControl(x,[Validators.required,Validators.email])),
[alertContactsArrayValidator()]),
});
FormsControls 需要电子邮件验证器和自定义验证器数组
我有一个与我的 FormArray 一起使用的自定义验证器,只要 FormArray 的输入是 []
,验证器就可以正常工作。但是,如果我为 FormArray 提供 string[]
或 FormControl[]
,验证器将破坏整个 angular 应用程序并导致无限循环错误。
我真的不确定是什么导致了这种情况发生。我需要能够用元素实例化 FormArray,所以我需要它才能工作。
起初我认为问题是由于我将 string[]
传递给 FormArray 而不是 FormControl[]
,但即使在将数组映射到 FormControls 数组之后我得到同样的问题。
this.alertData.alertContacts
只是一个电子邮件字符串数组。
FormGroup 实例化 - 有效
this.form = this.formBuilder.group({
alertContacts: this.formBuilder.array([], [Validators.required, alertContactsArrayValidator()]),
});
FormGroup 实例化 - 损坏
this.form = this.formBuilder.group({
alertContacts: this.formBuilder.array(this.alertData.alertContacts, [Validators.required, alertContactsArrayValidator()]),
});
FormGroup 实例化 - 损坏
this.form = this.formBuilder.group({
alertContacts: this.formBuilder.array(this.alertData.alertContacts.map(x => new FormControl(x)), [Validators.required, alertContactsArrayValidator()]),
});
自定义验证器
export function alertContactsArrayValidator(): ValidatorFn {
return (c: AbstractControl): { [key: string]: any } | null => {
let formArray = <FormArray>c;
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;
};
}
您需要检查 control.errors 是否为空。
formControls.forEach(control => {
let controlErrors: ValidationErrors = control.errors;
if (controlErrors){ //<---this "if"
Object.keys(controlErrors).forEach(key => {
if (key === 'email') {
hasEmailErrors = true;
console.log("key has email");
}
});
}
});
你也可以更简单
formControls.forEach(control => {
if (control.errors && control.errors.email){
hasEmailErrors = true;
console.log("key has email");
}
});
甚至
formControls.forEach(control => {
hasEmailErrors = hasEmailErrors ||
(control.errors && control.errors.email)
}
});
注意:我想你想要
this.form = this.formBuilder.group({
alertContacts: this.formBuilder.array(this.alertData.alertContacts
.map(x => new FormControl(x,[Validators.required,Validators.email])),
[alertContactsArrayValidator()]),
});
FormsControls 需要电子邮件验证器和自定义验证器数组