我正在构建自己的表单控件。
在字段循环中,我将FormControls
添加到FormGroup
。但是,当我尝试定义验证器组成时,会抛出ExpressionChangedAfterItHasBeenCheckedError
这是示例应用程序。
https://stackblitz.com/edit/angular-1j7x8p?file=src%2Fapp%2Fmy-input.component.ts
打开控制台。
使用Validators.compose([Validators.required])
,一切正常。
答案 0 :(得分:1)
你好,你有一个非常有趣的案例。
因此,让我们深入研究代码的作用
<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 } },
]
在这里{{1}中fields
中每个现有字段中,Angular正在渲染输入字段,并且在这样做的过程中,它也填充了{{1 }}
因此,一开始您有一个有效 AppComponent
,该字段为空且有效。第一次遍历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
是有效的,并且我们仍处于 {{1 }} my-input.component
(也就是父母)的救生钩。
第二次输入ngFor
组件后,我们看到来自formGroup
的第二个对象具有ngOnInit
属性。因此,我们将新的formControl添加到正在使用的AppComponent
中(从my-input.component
开始),并且此表单控件现在具有必需的验证器,但内部也没有任何值,该值立即生效触发添加的验证器,并使fields
无效。这样,我们更改validators
的{{1}}属性的状态,并触发formGroup
错误。
希望对您有所帮助。