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():

По умолчанию он также обновляет значение и действительность своих предков.

но в моем случае мне нужно обновить значение и срок действия его потомков. Так что я могу избавиться от многих строк кода.

Ответ 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);
    }
  }