Mat Table中的嵌套反应形式无法找到控件

时间:2018-10-08 15:55:24

标签: angular typescript angular-material angular6 angular-reactive-forms

我正在尝试使用反应式表格和材料表格在表格中构建表格。

我想允许用户向表中添加一行,然后对其进行编辑,因此在我的主FormGroup中(除了表中的其他字段,还有其他字段),我放置了一个FormArray,单击该按钮即可添加本身就是一个内部形式组。 该FormGroup具有多个FormControl,其中每一行都是一个独立的FormGroup,并具有自己的控件。

由于每行都是动态创建的,因此无法为该表单组指定名称,因此我使用了Material Table索引来尝试访问表单组。

我的问题是找不到内部控件(“错误:找不到名称为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 :(得分:0)

首先,在您的mat-table中,我认为您需要一个带有FormArray控件的FormGroup,该控件具有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"来设置值,也可以在创建表单结构时预先填充它。

Google提供的示例可能会有所帮助: https://stackblitz.com/edit/angular-riepzk-rp5jbf?file=app%2Ftable-basic-example.ts

免责声明:我尚未测试此代码,但这应该是正确的。 希望对您有帮助!