使用 FormArray 的角度材质可编辑表 [英] Angular Material editable table using FormArray
问题描述
我正在尝试使用最新的材料+cdk 来构建一个内嵌的可编辑表格.
问题
<块引用>如何让 mat-table 使用 [formGroupName]
以便表单字段可以被正确的表单路径引用?
这是我目前得到的:完整的 StackBlitz 示例
模板
<h1>不起作用</h1><table mat-table [dataSource]="dataSource" formArrayName="dates"><!-- 行定义--><tr mat-header-row *matHeaderRowDef="displayColumns"></tr><tr mat-row *matRowDef="let row; let i = index; columns: displayColumns;"[formGroupName]="i"></tr><!-- 列定义--><ng-container matColumnDef="from"><th mat-header-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-header-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"
For solving problems with sorting and filtering take a look at this answer Angular Material Table Sorting with reactive formarray
这篇关于使用 FormArray 的角度材质可编辑表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!