Angular2 - проверка имени FormControlName в дочернем компоненте родительской FormGroup

У меня есть компонент angular, соответствующий форме/странице, которая генерирует неопределенное количество дочерних компонентов, каждая из которых представляет отдельное поле, и я хотел бы, чтобы родительский компонент FormGroup проверял поля, содержащиеся в дочерних компонентах. Только когда я это сделаю, я получаю сообщение об ошибке:

A FormControlName должен иметь соответствующую группу форм.

Вот код шаблона для моего родительского компонента:

<div class="form-group" [formGroup]="parentGroup">
  <table>
    <tbody>
      <tr *ngFor="let i of array">
        <child [property]="i" [options]="myForm.controls[i.id]"></child>
      </tr>
    </tbody>
  </table>
</div>

Форма определяется здесь в файле компонента. Я добавляю FormControls в соответствии с количеством дочерних компонентов, которые мы добавляем:

private formAttrs: FormGroup;

constructor(private _fb: FormBuilder) { }

ngOnInit() {
  this.myForm = this._fb.group({});
  for (var i = 0; i < this.array.length; i++) {
    this.formAttrs.addControl(this.array[i].id, new FormControl(this.array[i].value, Validators.required));
  }
}

Код шаблона для дочернего компонента таков:

<td class="prompt">
  {{i.label}}
</td>
<td class="required" width="1%">
  <span *ngIf="property.required">*</span>
</td>
<td>
  <input type="text " class="form-control" [ngClass]="{error: !options.valid}" formControlName="property.id">
</td>
<td>

Пока в классе дочерних компонентов нет ничего определенного (кроме свойства "свойство" и элемента FormControl, переданного для "параметров" ), я бы подумал, что formGroup в родительском компоненте сможет соответствовать с formControlName в дочернем компоненте, но вместо этого я получаю ошибку:

EXCEPTION: Error in ./ChildComponent class ChildComponent - inline 
template:7:109 caused by: formControlName must be used with a parent 
formGroup directive.  You'll want to add a formGroup directive and pass 
it an existing FormGroup instance (you can create one in your class).

Есть ли способ обойти эту ошибку? Если нет, есть ли другое решение этой проблемы, которое может предложить кто-то?

Спасибо заранее.

Ответ 1

Есть несколько вещей, которые мне удалось реализовать в Plunker.

Во-первых, нам нужно передать в нашей формеGroup от родителя к дочернему элементу, поэтому у нас есть FormGroup, чтобы обеспечить принудительное принудительное использование шаблонов приложением FormControls, входящим в состав FormGroup:

child.component.ts

@Input() parentGroup: FormGroup;

child.component.html

<td [formGroup]="parentGroup">
<...>
</td>

Затем нам также нужно установить [formControl] или оценить property.id, иначе он будет искать имя "property.id":

<input type="text " class="form-control" [ngClass]="{error: !options.valid}" [formControl]="options"/>

или

<input type="text " class="form-control" [ngClass]="{error: !options.valid}" formControlName="{{property.id}}"/>

В вашем коде использовались разные переменные, связывающие formGroup и используя formAttrs, который был немного неясен в отношении того, что происходило, поэтому я пошел вперед и свернул их на один, и вы можете видеть, что в Plunker: http://plnkr.co/edit/3MRiO9bGNFAkN2HNN7wg?p=preview

Ответ 2

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

Вам нужно объявить собственную группу форм для каждого дочернего компонента, а затем вы можете перебирать ее в родительском компоненте на основе вашего ссылочного атрибута. Вы можете получить управление каждым дочерним элементом с помощью метода компонента-указателя FormGroupDirective.getControl(controlName), как вы можете видеть в документации: https://angular.io/docs/ts/latest/api/forms/index/FormGroupDirective-directive.html