You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 5响应式表单:FormArray多实例及值填充问题

解决方案:在*ngFor中生成多个FormGroup并从JSON填充值

1. 问题根源分析

你当前的代码初始化时只往products这个FormArray里添加了一个initProducts()生成的FormGroup,所以模板里自然只能看到一个实例。另外,你还需要根据prodData的内容,为每个数据项创建对应的FormGroup并填充值。

2. 组件代码修改

首先调整表单初始化逻辑,让它根据prodData的长度生成对应数量的FormGroup,同时填充数据。另外添加一个getter方便模板访问FormArray:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  productionForm!: FormGroup;
  // 这里替换为你实际的prodData结构
  prodData = [
    { begTally: 10, endTally: 20 },
    { begTally: 15, endTally: 25 }
  ];

  constructor(private fb: FormBuilder) {}

  // 获取products FormArray的快捷访问器
  get productsFormArray() {
    return this.productionForm.get('products') as FormArray;
  }

  initProducts(): FormGroup {
    return this.fb.group({
      begTally: ['', Validators.required],
      endTally: ['', Validators.required],
    });
  }

  ngOnInit() {
    // 初始化空的FormArray
    const productsArray = this.fb.array([]);

    // 遍历prodData,为每个数据创建FormGroup并填充值
    this.prodData.forEach(item => {
      const productGroup = this.initProducts();
      // 用patchValue匹配键名填充数据
      productGroup.patchValue(item);
      productsArray.push(productGroup);
    });

    // 创建主表单
    this.productionForm = this.fb.group({
      products: productsArray
    });
  }

  // 可选:添加新的产品表单组功能
  addProduct() {
    this.productsFormArray.push(this.initProducts());
  }
}

3. 模板代码调整

模板里需要正确绑定FormArray和每个FormGroup,用*ngFor遍历FormArray的controls:

<form [formGroup]="productionForm">
  <div formArrayName="products">
    <!-- 遍历每个FormGroup,用索引绑定formGroupName -->
    <div *ngFor="let product of productsFormArray.controls; let i = index" [formGroupName]="i">
      <label>产品 {{ i + 1 }}</label>
      <input 
        type="number" 
        formControlName="begTally" 
        placeholder="期初计数"
        required
      >
      <input 
        type="number" 
        formControlName="endTally" 
        placeholder="期末计数"
        required
      >
    </div>
  </div>

  <!-- 可选:点击新增产品表单 -->
  <button (click)="addProduct()">添加新产品</button>

  <!-- 打印表单值用于调试 -->
  <pre>{{ productionForm.value | json }}</pre>
</form>

4. 关键细节说明

  • productsFormArray getter:避免在模板里写冗长的类型断言,让模板代码更简洁易读。
  • patchValue:自动匹配控件名和JSON的键名完成赋值,非常适合从外部数据填充表单的场景。
  • *ngFor遍历productsFormArray.controls:每个迭代项对应一个FormGroup,通过[formGroupName]="i"绑定到数组的索引位置,确保表单控件和FormGroup正确关联。

这样修改后,你就能看到和prodData长度一致的表单组,每个控件都会被正确填充初始值,点击添加按钮还能新增空的表单组。

内容的提问来源于stack exchange,提问作者JordanBarber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:10:30