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

Angular表单数组实现问题:需设置动态键值求解决方案

Angular FormArray 动态键值实现方案

核心思路

默认FormArray仅支持数字索引作为键,要实现自定义动态键,需改用FormGroup存储动态项(FormGroup允许任意字符串作为键),通过keyvalue管道遍历键值对渲染动态表单。


1. 组件TS代码修改

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

export class YourComponent {
  addServiceForm: FormGroup;
  registrationForm: FormGroup;
  banking = 11;
  isSubmitted = false;

  constructor(private fb: FormBuilder) {
    this.initForms();
  }

  // 初始化表单结构
  initForms() {
    this.addServiceForm = this.fb.group({
      service_name: ['', Validators.required]
      // 其他主表单控件
    });

    // 用FormGroup替代原FormArray,存储动态键的计划项
    this.registrationForm = this.fb.group({
      addDynamicElement: this.fb.group({})
    });
  }

  // 获取动态计划的FormGroup
  get dynamicPlansGroup(): FormGroup {
    return this.registrationForm.get('addDynamicElement') as FormGroup;
  }

  // 添加动态计划(生成唯一键)
  addPlan() {
    // 生成唯一动态键(示例用时间戳,可替换为业务唯一标识如计划ID)
    const dynamicKey = `plan_${Date.now()}`;
    // 创建单个计划的表单组
    const planForm = this.fb.group({
      plan_name: ['', Validators.required],
      price: ['', Validators.required],
      // 其他计划相关控件
    });
    // 将新计划添加到动态组中
    this.dynamicPlansGroup.addControl(dynamicKey, planForm);
  }

  // 删除指定键的计划
  removePlan(key: string) {
    this.dynamicPlansGroup.removeControl(key);
  }

  // 表单提交处理
  onSubmit() {
    this.isSubmitted = true;
    if (this.addServiceForm.invalid || this.registrationForm.invalid) return;

    // 合并主表单与动态计划表单的值
    const submitData = {
      ...this.addServiceForm.value,
      ...this.registrationForm.value
    };
    console.log('提交数据:', submitData);
    // 后续提交逻辑
  }
}

2. 模板HTML代码修改

<!-- 主表单 -->
<form [formGroup]="addServiceForm">
  <div class="row">
    <div class="col-sm-12 col-md-4 col-lg-4">
      <mat-form-field class="example-full-width" appearance="outline">
        <mat-label>Service name</mat-label>
        <input type="text" matInput placeholder="Ex. Fairbet" formControlName="service_name">
        <mat-error *ngIf="isSubmitted && addServiceForm.get('service_name')?.hasError('required')">Service name is required</mat-error>
      </mat-form-field>
    </div>
    <!-- 其他主表单字段 -->
  </div>

  <!-- 动态计划表单区域 -->
  <div *ngIf="banking == 11">
    <div class="row">
      <div [formGroup]="registrationForm">
        <div class="d-flex justify-content-between mb-2">
          <h5>Add Plan</h5>
          <div class="d-flex justify-content-between">
            <button class="btn btn-sm d-flex align-items-center mx-1 btn-success" (click)="addPlan()">
              <mat-icon>add</mat-icon>
            </button>
          </div>
        </div>

        <!-- 遍历动态键值对渲染计划项 -->
        <div formGroupName="addDynamicElement">
          <div class="row mb-4 position-relative" 
               *ngFor="let item of dynamicPlansGroup.controls | keyvalue; let i = index" 
               [formGroupName]="item.key">
            <!-- 计划名称输入框 -->
            <div class="col-sm-12 col-md-3 col-lg-3">
              <mat-form-field class="example-full-width" appearance="outline">
                <mat-label>Plan Name</mat-label>
                <input type="text" matInput formControlName="plan_name">
                <mat-error *ngIf="isSubmitted && item.value.get('plan_name')?.hasError('required')">Plan name is required</mat-error>
              </mat-form-field>
            </div>
            <!-- 价格输入框 -->
            <div class="col-sm-12 col-md-3 col-lg-3">
              <mat-form-field class="example-full-width" appearance="outline">
                <mat-label>Price</mat-label>
                <input type="number" matInput formControlName="price">
                <mat-error *ngIf="isSubmitted && item.value.get('price')?.hasError('required')">Price is required</mat-error>
              </mat-form-field>
            </div>
            <!-- 删除按钮 -->
            <div class="col-sm-12 col-md-1 col-lg-1 d-flex align-items-end">
              <button class="btn btn-sm btn-danger" (click)="removePlan(item.key)">
                <mat-icon>delete</mat-icon>
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- 提交按钮 -->
  <button class="btn btn-primary mt-3" (click)="onSubmit()">Submit</button>
</form>

关键说明

  • 用FormGroup替代FormArray:FormArray仅支持数字索引,FormGroup可自定义任意字符串作为键,满足动态键需求
  • keyvalue管道:用于遍历FormGroup的键值对,获取每个动态项的键和对应的表单组
  • 动态键生成:示例用时间戳保证唯一性,可根据业务需求替换为用户输入的唯一标识(如计划ID)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 07:22:53