使用 FormArray 的角度材质可编辑表 [英] Angular Material editable table using FormArray

查看:23
本文介绍了使用 FormArray 的角度材质可编辑表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用最新的材料+cdk 来构建一个内嵌的可编辑表格.

问题

<块引用>

如何让 mat-table 使用 [formGroupName] 以便表单字段可以被正确的表单路径引用?

这是我目前得到的:完整的 StackBlitz 示例

模板

<h1>作品</h1><div formArrayName="dates" *ngFor="let date of rows.controls; let i = index;"><div [formGroupName]="i"><input type="date" formControlName="from" placeholder="From date"><input type="date" formControlName="to" placeholder="To date">

<h1>不起作用</h1><table mat-table [dataSource]="dataSource" formArrayName="dates"><!-- 行定义--><tr mat-h​​eader-row *matHeaderRowDef="displayColumns"></tr><tr mat-row *matRowDef="let row; let i = index; columns: displayColumns;"[formGroupName]="i"></tr><!-- 列定义--><ng-container matColumnDef="from"><th mat-h​​eader-cell *matHeaderCellDef>来自</th><td mat-cell *matCellDef="let row"><input type="date" formControlName="from" placeholder="From date"></td></ng-容器><ng-container matColumnDef="to"><th mat-h​​eader-cell *matHeaderCellDef>到</th><td mat-cell *matCellDef="let row"><input type="date" formControlName="to" placeholder="To date"></td></ng-容器><button type="button" (click)="addRow()">添加行</button></表单>

组件

导出类 AppComponent 实现 OnInit {数据:TableData[] = [ { from: new Date(), to: new Date() } ];dataSource = new BehaviorSubject([]);displayColumns = ['from', 'to'];行:FormArray = this.fb.array([]);表单:FormGroup = this.fb.group({'dates': this.rows });构造函数(私人FB:FormBuilder){}ngOnInit() {this.data.forEach((d: TableData) => this.addRow(d, false));this.updateView();}空表(){while (this.rows.length !== 0) {this.rows.removeAt(0);}}addRow(d?: TableData, noUpdate?: boolean) {const row = this.fb.group({'来自' : [d &&d.从?d.from : null, []],'到' : [d &&d. 到 ?d.to : null, []]});this.rows.push(row);if (!noUpdate) { this.updateView();}}更新视图(){this.dataSource.next(this.rows.controls);}}

问题

这行不通.控制台收益

<块引用>

错误错误:找不到路径控制:'日期 -> 来自'

似乎 [formGroupName]="i" 没有效果,因为路径应该是 dates ->0 ->来自 使用 formArray 时.

我目前的解决方法:对于这个问题,我绕过了内部路径查找 (formControlName="from") 并直接使用表单控件:[formControl]="row.get('from')",但我想知道我如何(或至少为什么我不能)使用响应式表单的首选方式.

欢迎提供任何提示.谢谢.

<小时>

因为我认为这是一个错误,所以我已经在一个问题angular/material2 github 存储库.

解决方案

我会使用我们可以在 matCellDef 绑定中获得的索引:

*matCellDef="let row;让索引 = 索引"[formGroupName]=索引"

分叉堆叠闪电战

要解决排序和过滤问题,请查看此答案 使用反应式表单数组进行角度材料表排序

I'm trying to build an inline editable table using the latest material+cdk for angular.

Question

How can I make mat-table use [formGroupName] so that the form fields can be referenced by its correct form path?

This is what I got so far: Complete StackBlitz example

Template

<form [formGroup]="form">
  <h1>Works</h1>
  <div formArrayName="dates" *ngFor="let date of rows.controls; let i = index;">
    <div [formGroupName]="i">
      <input type="date" formControlName="from" placeholder="From date">
      <input type="date" formControlName="to" placeholder="To date">
    </div>
  </div>


  <h1>Wont work</h1>
  <table mat-table [dataSource]="dataSource" formArrayName="dates">
    <!-- Row definitions -->
    <tr mat-header-row *matHeaderRowDef="displayColumns"></tr>
    <tr mat-row *matRowDef="let row; let i = index; columns: displayColumns;" [formGroupName]="i"></tr>

    <!-- Column definitions -->
    <ng-container matColumnDef="from">
      <th mat-header-cell *matHeaderCellDef> From </th>
      <td mat-cell *matCellDef="let row"> 
        <input type="date" formControlName="from" placeholder="From date">
      </td>
    </ng-container>

    <ng-container matColumnDef="to">
      <th mat-header-cell *matHeaderCellDef> To </th>
      <td mat-cell *matCellDef="let row">
        <input type="date" formControlName="to" placeholder="To date">
      </td>
    </ng-container>
  </table>
  <button type="button" (click)="addRow()">Add row</button>
</form>

Component

export class AppComponent implements  OnInit  {
  data: TableData[] = [ { from: new Date(), to: new Date() } ];
  dataSource = new BehaviorSubject<AbstractControl[]>([]);
  displayColumns = ['from', 'to'];
  rows: FormArray = this.fb.array([]);
  form: FormGroup = this.fb.group({ 'dates': this.rows });

  constructor(private fb: FormBuilder) { }

  ngOnInit() {
    this.data.forEach((d: TableData) => this.addRow(d, false));
    this.updateView();
  }

  emptyTable() {
    while (this.rows.length !== 0) {
      this.rows.removeAt(0);
    }
  }

  addRow(d?: TableData, noUpdate?: boolean) {
    const row = this.fb.group({
      'from'   : [d && d.from ? d.from : null, []],
      'to'     : [d && d.to   ? d.to   : null, []]
    });
    this.rows.push(row);
    if (!noUpdate) { this.updateView(); }
  }

  updateView() {
    this.dataSource.next(this.rows.controls);
  }
}

Problem

This wont work. Console yields

ERROR Error: Cannot find control with path: 'dates -> from'

It seems as if the [formGroupName]="i" has no effect, cause the path should be dates -> 0 -> from when using a formArray.

My current workaround: For this problem, I've bypassed the internal path lookup (formControlName="from") and use the form control directly: [formControl]="row.get('from')", but I would like to know how I can (or at least why I cannot) use the Reactive Form preferred way.

Any tips are welcome. Thank you.


Since I think this is a bug, I've registered an issue with the angular/material2 github repo.

解决方案

I would use the index which we can get within matCellDef binding:

*matCellDef="let row; let index = index" [formGroupName]="index"

Forked Stackblitz

For solving problems with sorting and filtering take a look at this answer Angular Material Table Sorting with reactive formarray

这篇关于使用 FormArray 的角度材质可编辑表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆