首页 > 解决方案 > 编写验证器时出错

问题描述

我正在构建自己的表单控件。在我添加FormControls到的字段循环中FormGroup。但是当我尝试定义验证器组合时,它会抛出我ExpressionChangedAfterItHasBeenCheckedError

这是示例应用程序。 https://stackblitz.com/edit/angular-1j7x8p?file=src%2Fapp%2Fmy-input.component.ts 打开控制台。与Validators.compose([Validators.required])所有作品。

标签: angular

解决方案


你好,你有一个非常有趣的案例。

因此,让我们深入了解您的代码在做什么

<form [formGroup]="formGroup">
  <my-input *ngFor="let field of fields" [formGroup]="formGroup" [field]="field"></my-input>
</form>

在哪里

 formGroup = new FormGroup({}, { updateOn: 'submit' });

 fields = [
      { id: 'id', name: 'name' },
      { id: 'id2', name: 'name2', validators: { required: true } },
 ]

fields在这里,对于您中的每个现有字段AppComponent,Angular 正在渲染输入字段,并且在此过程中,它还将formGroup对象填充到AppComponent

所以一开始你有一个有效 formGroup的,它是空的和有效的。在第一次遍历您的fields集合后,在您my-input.component的内部插入一个表单控件,该控件formGroup从父组件传递到子组件的ngOnInit生命钩子中(同时仍在ngOnInit父元素的生命钩子中)。

 If (!this.formGroup.contains(this.field.id)) {
    this.formGroup.addControl(
    this.field.id,
    New FormControl(
      undefined, 
      this.getValidators(this.field.validators)
    )
  );
}

您还将fields通过以下函数根据来自父级的输入添加错误验证器。

private getValidators(validators) {
  if (validators) {
    const ngValidators = [];
    for (const validatorName in validators) {
      if (Validators[validatorName]) {
        ngValidators.push(Validators[validatorName]);
      }
    }
    return Validators.compose(ngValidators);
  }
  return Validators.compose([]);
}

此时,您已经呈现了第一个输入并formGrop用一个表单控件填充了该控件,该控件没有任何验证器(因为该字段的配置中没有任何验证器)。

所以现在在my-input.component第二次通过ngForour进入之前formGroup有效的,我们仍然处于(换句话说就是父级)的ngOnInit生命钩子中。AppComponent

在我们第二次进入my-input.component组件后,我们看到第二个对象 fromfields具有validators属性。多亏了我们现在formGroup(从内部my-input.component)向我们正在使用的表单控件添加新的表单控件,并且这个表单控件现在有一个必需的验证器,但它内部也没有值,这会立即触发添加的验证器,并使formGroup 无效的. 通过这样做,我们正在更改formGroup'属性的状态Valid并触发expression changed after it has been checked错误。

我希望这对你有所帮助。


推荐阅读