Вложенные реактивные формы в Mat Table не могут найти контроль - PullRequest
0 голосов
/ 08 октября 2018

Я пытаюсь построить форму в таблице, используя как реактивные формы, так и таблицу материалов.

Я бы хотел, чтобы пользователи могли добавить строку в таблицу, а затем отредактировать ее, поэтому в моей основной группе FormGroup (есть другие поля, кроме тех, что в таблице), я поместил FormArray, которыйпо клику добавляет себе внутреннюю форму группы.Эта FormGroup имеет несколько FormControls внутри таким образом, что каждая строка является независимой FormGroup и имеет свои собственные элементы управления.

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

Моя проблемачто внутренний элемент управления не найден («Ошибка: не удается найти элемент управления с именем XXX»), полагаю, я сделал его более сложным, чем должно быть, поэтому я хотел бы получить ваш совет о том, как это сделать.

html

<form [formGroup]="contaningFG">
  <some other forms...>
  <button (click)="addRow">Add row</button>
  <table mat-table [dataSource]="dataSource">

        <!-- First Column -->
        <ng-container matColumnDef="FirstColumn">
          <th mat-header-cell *matHeaderCellDef> FirstColumn </th>
          <td mat-cell *matCellDef="let element">
            <mat-form-field>
              <input matInput [formControlName]="myFirstFC">
            </mat-form-field>
          </td>
        </ng-container>

        <!-- Second Column -->
        <ng-container matColumnDef="SecondColumn">
          <th mat-header-cell *matHeaderCellDef> Second Column </th>
          <td mat-cell *matCellDef="let element">
            <mat-form-field>
              <input matInput [formControlName]="mySecondFC">
            </mat-form-field>
          </td>
        </ng-container>

        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
        <tr mat-row *matRowDef="let row; columns: displayedColumns; let i = index"
          [formGroup]="innerFA.controls[i]"></tr>
  </table>
</from>

ts

public containingFG = new FormGroup({
  "foo": new FormControl(),
  "bar": new FormControl(true),
});
public innerFA = new FormArray([]);

public dataSource: MatTableDataSource<AbstractControl>;
public displayedColumns = [
  "FirstColumn",
  "SecondColumn"
]

constructor() {
  this.dataSource = new MatTableDataSource();
}

ngOnInit() {
  this.containingFG.addControl("innerForms", this.innerFA);
  this.dataSource.data = this.innerFA.controls;
}

addRow() {
  this.customersForm.push(new FormGroup({
    "firstColumn": new FormControl("hi"),
    "secondColumn": new FormControl("hello")
  }));
  this.customersDataSource._updateChangeSubscription();
}

1 Ответ

0 голосов
/ 09 февраля 2019

Прежде всего, в вашем mat-table Я думаю, что вам требуется FormGroup с элементом управления FormArray, который имеет FormGroups (это элементы управления в строке таблицы).

Что-то вроде:

const group = new FormGroup( {
  rows: new FormArray( [
    new FormGroup( {
      foo: new FormControl(1),
      bar: new FormControl(1)
    } ),
    new FormGroup( {
      foo: new FormControl(2),
      bar: new FormControl(2)
    })
  ])
} );

Конечно, вы можете создать функцию, которая создаст для вас структуру Row FormGroup.

<div [formGroup]="group" class="mat-elevation-z1" #tableWrapper>
  <table mat-table [dataSource]="data" formArrayName="rows">

    <ng-container matColumnDef="foo">
      <th mat-header-cell *matHeaderCellDef>Foo</th>
      <td mat-cell *matCellDef="let row; let i = index" [formGroupName]="i">

        <mat-form-field class="input">
          <input matInput formControlName="foo">
        </mat-form-field>
     </td>
   </ng-container>

    <ng-container matColumnDef="bar">
      <th mat-header-cell *matHeaderCellDef>Bar</th>
      <td mat-cell *matCellDef="let row; let i = index" [formGroupName]="i">

        <mat-form-field class="input">
          <input matInput formControlName="bar">
        </mat-form-field>
     </td>
   </ng-container>


   <tr mat-header-row *matHeaderRowDef="displayColumns; sticky: true"></tr>
   <tr mat-row *matRowDef="let row; columns: displayColumns; let i = index"></tr>
</table>

Наконец вам нужно добавить свои данные:

const data = [
{ foo: 1, bar: 1 },
{ foo: 2, bar: 2 },
]

Если яправильно, данные, которые вы передаете в mat-table, должны присутствовать в вашей структуре FormArray, поэтому вы должны пропатчить значения.Я думаю, что функция источника данных состоит в том, чтобы печатать значения в каждом mat-cell, используя переменную row.Однако, поскольку вы используете formControl, вы можете либо использовать [value]="row.foo" in для установки значения, либо предварительно заполнить его при создании структуры формы.

Пример Google, который может помочь: https://stackblitz.com/edit/angular-riepzk-rp5jbf?file=app%2Ftable-basic-example.ts

Отказ от ответственности: я не проверял этот код, но он должен быть примерно правильным.Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...