Dans mon application Angular 4, j'ai un formulaire avec plusieurs contrôles.
À certains moments, je dois forcer la mise à jour de leur validité, alors je fais:
this.form.get('control1').updateValueAndValidity();
this.form.get('control2').updateValueAndValidity();
this.form.get('control3').updateValueAndValidity();
// and so on....
et alors:
this.form.updateValueAndValidity();
cela fonctionne bien.
Cependant, je me demandais s'il y avait une meilleure façon d'accomplir la même chose, en appelant simplement une méthode sur le formulaire parent.
Selon son documentation , la méthode updateValueAndValidity()
:
Par défaut, il mettra également à jour la valeur et la validité de ses ancêtres .
mais dans mon cas, je dois mettre à jour la valeur et la validité de ses descendants . Je peux donc me débarrasser de nombreuses lignes de code.
Il n'est pas possible pour le moment de mettre à jour les descendants d'un AbstractControl (FormGroup, ...) avec le AbstractControl lui-même. Peut-être que dans une prochaine version, ce sera possible.
https://github.com/angular/angular/issues/617
https://github.com/angular/angular/issues/22166
mise à jour: une demande d'extraction est déjà ouverte https://github.com/angular/angular/pull/19829
J'ai résolu mon problème, qui était similaire au vôtre, en récurant les contrôles et en déclenchant manuellement la mise à jour. Ce n'est probablement pas une solution optimale:
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 });
}
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);
}
}