Angular form updateValueAndValidity всех дочерних элементов управления
В моем приложении Angular 4 у меня есть форма с несколькими элементами управления.
В некоторых моментах мне нужно принудительно обновить их действительность, поэтому я делаю:
this.form.get('control1').updateValueAndValidity();
this.form.get('control2').updateValueAndValidity();
this.form.get('control3').updateValueAndValidity();
// and so on....
а затем:
this.form.updateValueAndValidity();
это отлично работает.
Однако мне было интересно, есть ли лучший способ сделать то же самое, просто вызвав один метод в родительской форме.
Согласно документации, метод updateValueAndValidity()
:
По умолчанию он также обновляет значение и действительность своих предков.
но в моем случае мне нужно обновить значение и срок действия его потомков. Так что я могу избавиться от многих строк кода.
Ответы
Ответ 1
В настоящее время невозможно обновить потомков AbstractControl (FormGroup,...) с помощью самого AbstractControl. Возможно, в будущем выпуске это будет возможно.
https://github.com/angular/angular/issues/6170
https://github.com/angular/angular/issues/22166
обновление: пул-запрос уже открытhttps://github.com/angular/angular/pull/19829
Ответ 2
Я решил свою проблему, которая была похожа на вашу, повторно запустив элементы управления и вручную запустив обновление.
Вероятно, это не оптимальное решение:
private triggerValidation(control: AbstractControl) {
if (control instanceof FormGroup) {
const group = (control as FormGroup);
for (const field in group.controls) {
const c = group.controls[field];
this.triggerValidation(c);
}
}
else if (control instanceof FormArray) {
const group = (control as FormArray);
for (const field in group.controls) {
const c = group.controls[field];
this.triggerValidation(c);
}
}
control.updateValueAndValidity({ onlySelf: false });
}
Ответ 3
validateFormFields(fields) {
try {
Object.entries(fields.controls).forEach((control: any) => {
if (typeof control[0] == 'Array'
) {
this.validateFormFields(control[1]);
} else {
if (control[1].controls) {
Object.entries(control[1].controls).forEach((c: any) => {
c[1].touched = true;
});
} else {
control[1].touched = true;
}
}
});
} catch (e) {
console.log(e);
}
}