Angular 角度FORMARY自定义验证程序未启动

Angular 角度FORMARY自定义验证程序未启动,angular,validation,angular-reactive-forms,Angular,Validation,Angular Reactive Forms,在我的FormGroup中有一个FormArray,它将包含n个FormControls,每个FormControls都附带了一个电子邮件验证程序 我希望我的FormArray能够知道是否有任何FormControls有电子邮件验证错误,如果有,FormError errors属性应该设置为{email:true} 为此,我编写了一个应用于FormArray的自定义验证器。但是,当从FormArray中添加或删除FormControl元素时,此验证器似乎没有正确启动 this.form = th

在我的FormGroup中有一个FormArray,它将包含n个FormControls,每个FormControls都附带了一个电子邮件验证程序

我希望我的FormArray能够知道是否有任何FormControls有电子邮件验证错误,如果有,FormError errors属性应该设置为
{email:true}

为此,我编写了一个应用于FormArray的自定义验证器。但是,当从FormArray中添加或删除FormControl元素时,此验证器似乎没有正确启动

this.form = this.formBuilder.group({
      alertContacts: this.formBuilder.array(this.alertData.alertContacts, [Validators.required, alertContactsArrayValidator]),
    });
this.form = this.formBuilder.group({
      alertContacts: this.formBuilder.array([], [Validators.required, alertContactsArrayValidator]), //An empty array works fine
    });
此表单数组由一个子组件控制,该子组件在实例化时将对表单数组的引用作为输入传递给它。子组件中向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();
  }
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;
  };
}
我的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();
  }
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(this.alertData.alertContacts, [Validators.required, alertContactsArrayValidator]),
    });
this.form = this.formBuilder.group({
      alertContacts: this.formBuilder.array([], [Validators.required, alertContactsArrayValidator]), //An empty array works fine
    });

如果我想用已经在FormArray中的元素实例化FormArray,我应该以不同的方式来执行它,而不仅仅是将数组作为
this.formBuilder.array()
方法的第一个参数来传递吗?

验证器不同,
验证器fn
应该手动触发(Angular不调用它本身来让您通过一些有用的配置)如下所示:

this.form=this.formBuilder.group({
alertContacts:this.formBuilder.array(
此.alertData.alertContacts,
[Validators.required,alertContactsArrayValidator()]
),
});
编辑:

this.form=this.formBuilder.group({
alertContacts:this.formBuilder.array(
this.alertData.alertContacts.map(x=>newformControl(x[
需要验证器,
alertContactsArrayValidator()
])),
),
});

看,我试过了。但是当我这么做的时候,我的应用程序陷入了一个无限的错误循环。我实际上发现了一些东西。我会编辑这个操作。
@Jake12342134
FormArray
接受一个
FormControl
的数组。有没有一种简单的方法可以将字符串数组传递给formBuilder.array方法,或者我需要创建一个到c的方法将
string[]
转换为
FormControl[]
this.alertData.alertContacts.map(x=>newformcontrol(x))
不起作用,我仍然会遇到这个导致无限循环的奇怪错误。