Угловые реактивные формы AddControl Вызывает ExpressionChangedAfterItHasBeenCheckedError при использовании PatchValue
Я хотел иметь возможность создавать реактивную форму, используя компоненты, но не настраивать ее в одном родительском компоненте. Итак, я создал начальный FormGroup
и передал его компонентам, которые затем делают this.form.addControl(this.fb.group({ ... }));
добавить свою группу в форму.
пример
Родительский компонент
this.form = this.fb.group({}); // Empty
public ngAfterViewInit() {
// Throws error after trying to patchValue on the child component
this.form.get('example').patchValue({
field1: 'Hello World!'
});
}
Дочерние компоненты
this.parentFormGroup.addControl(
'childGroup',
this.fb.group({
field1: [
'', [Validators.required]
],
etc...
}
);
Это работает, пока я не попробую и this.form.get('childGroup').patchValue({ ... })
после подачи запроса в ngAfterViewInit
Хук жизненного цикла родительского компонента. Вместо исправления группы он выдает:
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has
changed after it was checked. Previous value: 'ng-valid: false'. Current value:
'ng-valid: true'.
Есть ли способ, чтобы дочерние компоненты добавляли себя в FormGroup
и не иметь родительской установки FormGroup
элементы управления и проверки. Нам нужно повторно использовать дочерние компоненты различными способами и комбинациями в приложении, поэтому мы не хотели повторять FormGroup
объявление вне дочерних компонентов, но это не похоже на работу.
1 ответ
Эта ошибка появляется, потому что, исправляя значение в ngAfterViewInit, вы меняете состояние валидности формы после того, как форма уже проверена логикой обнаружения изменений Angular.
У вас есть два варианта предотвратить это:
- Вы настраиваете форму таким образом, чтобы иметь непосредственно правильное состояние достоверности, например, передавая начальное значение дочернему элементу и устанавливая его там.
или же
Вы перемещаете установку значения в другой цикл обнаружения изменений, заключая patchValue в setTimeout:
setTimeout(() => this.form.get('childGroup').patchValue({ ... }))