И markAllAsTouched, и markAsTouched не влияют на подчиненные формы - PullRequest
0 голосов
/ 19 марта 2020

Справочная информация

У меня есть ОЧЕНЬ большая форма (потенциально сотни полей), которую я решил разбить на более мелкие компоненты субформы (по очевидным причинам). Я достиг этого, используя Access Value Accessors. Это работало как чудо, пока не пришло время показывать ошибки в полях при отправке.

Подформы сформированы так:

<form [formGroup]="form">
  <app-subform [documentId]="documentId" formControlName="sub-form"></app-subform>

  <!-- Other form fields here ... -->
</form>

Чтобы упростить свою работу, я создал компонент ошибок который принимает в качестве входных данных элемент управления, как в коде ниже. Код ниже является частью формы.

<div class="question">
  <label for="tableNumber">
    Figure/table number
    <app-required [type]="'conditional'"></app-required>
  </label>
  <input type="text" id="tableNumber" formControlName="figure"/>
  <app-error [control]="form.get('figure')"></app-error>
</div>

Внутренняя часть моей ошибки HTML выглядит примерно так:

<span class="errorWrapper" *ngIf="control.invalid && control.touched" (click)="clearError()" [innerHtml]="error"></span>

Пример кода

Хотя я не могу поделиться своим полным кодом, вот воспроизводство проблемы: https://stackblitz.com/edit/encapsulated-sub-forms

Проблема

Когда я отправляю свой код, чтобы получая сообщения об ошибках, отображаемые на каждом входе, я отмечаю все входы как прикосновенные, используя this.form.markAllAsTouched(); Хотя это работает как прелесть для входных данных, которые не являются частью компонентов субформы, сами компоненты субформы вообще не реагируют, оставаясь нетронутыми.

Решения, которые я рассмотрел

  • Моя первая реакция была - почему бы не пометить каждый элемент управления как индивидуальный? Не работает
  • Как насчет того, чтобы реализовать ввод для каждого компонента формы, при котором триггеры помечаются как затронутые? Не пытался, больше похоже на взлом, чем на лучшее решение
  • Измените мою реализацию на использование ControlContainer. Кажется наиболее перспективным

То, что я пробовал

Я пытался изменить реализацию для использования ControlContainer, но это сопряжено с собственным набором проблем (описано в отдельный вопрос о переполнении стека).

Мой вопрос

Итак, в общем, я хочу знать, как я могу получить свои данные в форме для отображения ошибок при отправке, следуя рекомендациям и с минимальным количеством переписать (мои приоритеты в этом порядке)?

Ответы [ 2 ]

1 голос
/ 19 марта 2020

Проблема здесь в том, что ваш компонент формы объявляет новый FormGroup экземпляр. Он ничего не знает об экземпляре FormGroup в родительском элементе управления.

Мой подход заключается в передаче вложенных групп форм в пределах root FormGroup от родительского элемента до подформ.

Это позволит вашим подформам обновлять группу форм в родительском элементе без необходимости двусторонней привязки. И события, инициируемые в группе форм, будут распространяться через подформы.

Пример кода

parent.component.ts

this.form = this.formBuilder.group({
  subGroup1: this.formBuilder.group({}),
  subGroup1: this.formBuilder.group({})
});

parent .component. html

<form [formGroup]="form">
  <app-sub-form-1 [form]="form.get('subGroup1')"></app-sub-form-1>
  <app-sub-form-2 [form]="form.get('subGroup2')"></app-sub-form-1>
</form>

sub-form1.component.ts

this.form.addControl('sub-group1-control1', new FormControl(''));
0 голосов
/ 19 марта 2020

это логика c, элемент управления - form.get('subForm'). И извините, я не могу найти хорошее решение по этому поводу. Я никогда не понимаю, зачем создавать пользовательский элемент управления формы, когда проще использовать компонент, см., Например, этот SO или этот пост от Томаса Траяна

Я предлагаю это Возможно, в каждом настраиваемом элементе управления формы нужно создать метод, чтобы пометить все прикосновения и вызовы из родительского элемента

...