Mat Table 中的嵌套反应表单找不到控件
Posted
技术标签:
【中文标题】Mat Table 中的嵌套反应表单找不到控件【英文标题】:Nested reactive forms within Mat Table cant find control 【发布时间】:2019-03-13 08:18:25 【问题描述】:我正在尝试使用反应式表单和材料表在表中构建一个表单。
我想允许用户在表格中添加一行,然后对其进行编辑,所以在我的主 FormGroup 中(除了表格中的字段之外还有其他字段),我放置了一个 FormArray,点击添加本身是一个内部形式组。 该 FormGroup 有几个 FormControls,其中每一行都是一个独立的 FormGroup 并有自己的控件。
由于每一行都是动态创建的,我无法为该表单组命名,因此我使用材料表索引来尝试访问表单组。
我的问题是找不到内部控件(“错误:找不到名称为 XXX 的控件”),我猜我让它变得比应有的复杂得多,所以我想请教一下如何去做吧。
<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】:首先,在您的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 结构中,因此您必须修补这些值。我认为数据源的功能是使用row
变量打印每个mat-cell
中的值。
但是,由于您使用的是 formControl,您可以使用 [value]="row.foo"
in 来设置值,或者在创建表单结构时预填充它。
Google 提供的一个可能有帮助的示例: https://stackblitz.com/edit/angular-riepzk-rp5jbf?file=app%2Ftable-basic-example.ts
免责声明:我没有测试过这段代码,但它应该是正确的。 希望对您有所帮助!
【讨论】:
以上是关于Mat Table 中的嵌套反应表单找不到控件的主要内容,如果未能解决你的问题,请参考以下文章
如何修复角度表单控件中的“找不到名称为 __v 的表单控件”错误?