具有 Angular 5 个响应式表单的 FormArray 的多个实例
Multiple Instances of FormArray with Angular 5 Reactive Forms
我有一个表单数组,我想为 *ngFor
循环的每次迭代复制它。我的表单在模型中的设置如下:
initProducts() {
return this.fb.group({
begTally: ['', Validators.required],
endTally: ['', Validators.required],
})
}
ngOnInit() {
this.productionForm = this.fb.group({
products: this.fb.array([
this.initProducts()
])
})
}
当我使用 {{ myform.value | json }}
在视图中打印表单时,我只看到表单数组的一次迭代。这是具有完整设置的 StackBlitz。我还想将我的 prodData json 中的值修补到表单控件中。不确定我做错了什么。
表单中的组数必须与标记中的组数相同。例如
this.productionForm = this.fb.group({
products: this.fb.array([
this.initProducts(),
this.initProducts(),
this.initProducts()
])
})
将解决此问题,这意味着您必须对 *ngFor
迭代的同一集合进行交互,并创建相同数量的 FormControls
在您的 Stackblitz 示例中,您并没有那么远!
这是我的建议:
this.productionForm = this.fb.group({
production: this.fb.array(
this.prodData
// for each...
.groups
.reduce((acc, group) => [
...acc,
// ...product of each group
...group.products.map(product =>
// create a form group
this.fb.group({
begTally: [product.begTally, Validators.required],
endTally: [product.endTally, Validators.required],
})
)
], [])
)
})
- 创建一个表单数组,需要将其包装成一个表单组(这里叫
production
)
- 然后使用
reduce
在组上循环,这样您就可以在每个组中的每个产品上循环
- 为他们每个人建立一个表单组
在视图中,这有点棘手,因为您想要访问未存储到表单中的数据。所以我们必须混合原始数据和我们表单中的数据:
<form [formGroup]="productionForm">
<table *ngFor="let group of prodData.groups; let i = index">
<thead>
<th class="group-name">
<span>{{group.name}}</span>
</th>
<th>Beginning Tally</th>
<th>Ending Tally</th>
<th>Total</th>
</thead>
<tbody formArrayName="production">
<tr *ngFor="let product of group.products; let j=index" [formGroupName]="i + j">
<td>{{product.name}}</td>
<td>
<input type="number" formControlName="begTally">
</td>
<td>
<input type="number" formControlName="endTally">
</td>
<td>
{{ product.begTally + product.endTally }}
</td>
</tr>
</tbody>
</table>
</form>
这是我对你的 Stackblitz 的分支,带有一个工作示例:
https://stackblitz.com/edit/angular-kvlxnp?file=src%2Fapp%2Fapp.component.ts
我有一个表单数组,我想为 *ngFor
循环的每次迭代复制它。我的表单在模型中的设置如下:
initProducts() {
return this.fb.group({
begTally: ['', Validators.required],
endTally: ['', Validators.required],
})
}
ngOnInit() {
this.productionForm = this.fb.group({
products: this.fb.array([
this.initProducts()
])
})
}
当我使用 {{ myform.value | json }}
在视图中打印表单时,我只看到表单数组的一次迭代。这是具有完整设置的 StackBlitz。我还想将我的 prodData json 中的值修补到表单控件中。不确定我做错了什么。
表单中的组数必须与标记中的组数相同。例如
this.productionForm = this.fb.group({
products: this.fb.array([
this.initProducts(),
this.initProducts(),
this.initProducts()
])
})
将解决此问题,这意味着您必须对 *ngFor
迭代的同一集合进行交互,并创建相同数量的 FormControls
在您的 Stackblitz 示例中,您并没有那么远!
这是我的建议:
this.productionForm = this.fb.group({
production: this.fb.array(
this.prodData
// for each...
.groups
.reduce((acc, group) => [
...acc,
// ...product of each group
...group.products.map(product =>
// create a form group
this.fb.group({
begTally: [product.begTally, Validators.required],
endTally: [product.endTally, Validators.required],
})
)
], [])
)
})
- 创建一个表单数组,需要将其包装成一个表单组(这里叫
production
) - 然后使用
reduce
在组上循环,这样您就可以在每个组中的每个产品上循环 - 为他们每个人建立一个表单组
在视图中,这有点棘手,因为您想要访问未存储到表单中的数据。所以我们必须混合原始数据和我们表单中的数据:
<form [formGroup]="productionForm">
<table *ngFor="let group of prodData.groups; let i = index">
<thead>
<th class="group-name">
<span>{{group.name}}</span>
</th>
<th>Beginning Tally</th>
<th>Ending Tally</th>
<th>Total</th>
</thead>
<tbody formArrayName="production">
<tr *ngFor="let product of group.products; let j=index" [formGroupName]="i + j">
<td>{{product.name}}</td>
<td>
<input type="number" formControlName="begTally">
</td>
<td>
<input type="number" formControlName="endTally">
</td>
<td>
{{ product.begTally + product.endTally }}
</td>
</tr>
</tbody>
</table>
</form>
这是我对你的 Stackblitz 的分支,带有一个工作示例:
https://stackblitz.com/edit/angular-kvlxnp?file=src%2Fapp%2Fapp.component.ts