具有 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