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

Angular响应式表单如何将FormGroup推入嵌套FormArray

Angular响应式表单动态新增训练组功能实现方案

你的现有代码逻辑方向正确,但存在TypeScript类型校验不通过、嵌套控件访问不规范的问题,按以下方式调整即可稳定运行:

核心问题说明

直接通过.controls[0].controls.sets链式访问嵌套控件时,TypeScript无法自动推导AbstractControl的具体类型,编译阶段会抛出类型错误,硬编码索引和重复的访问逻辑也不利于后续维护。

修正后的完整实现

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

@Component({
  selector: 'app-workout-record',
  templateUrl: './workout-record.component.html'
})
export class WorkoutRecordComponent implements OnInit {
  workoutForm!: FormArray;

  ngOnInit() {
    this.workoutForm = new FormArray([
      new FormGroup({
        name: new FormControl(''),
        sets: new FormArray([
          this.createSingleSetGroup()
        ])
      })
    ]);
  }

  // 封装getter快速访问嵌套的sets表单数组,统一做类型断言
  get setsList(): FormArray {
    return this.workoutForm.at(0).get('sets') as FormArray;
  }

  // 抽离单组训练的表单组创建逻辑,避免重复代码
  private createSingleSetGroup(): FormGroup {
    return new FormGroup({
      reps: new FormControl(null),
      weight: new FormControl(null)
    });
  }

  // 新增训练组方法
  public addSet() {
    this.setsList.push(this.createSingleSetGroup());
  }

  // 可选:配套训练组删除方法
  public removeSet(index: number) {
    this.setsList.removeAt(index);
  }
}

模板层配套绑定示例

<!-- 绑定第一个训练动作的表单组 -->
<form [formGroup]="workoutForm.at(0)">
  <div class="action-name">
    <label>训练动作名称</label>
    <input type="text" formControlName="name" placeholder="例:杠铃卧推">
  </div>

  <!-- 绑定sets嵌套表单数组 -->
  <div formArrayName="sets">
    <h4>训练组记录</h4>
    <div *ngFor="let set of setsList.controls; let i = index" [formGroupName]="i" class="set-item">
      <span>第{{i+1}}组</span>
      <label>
        次数:
        <input type="number" formControlName="reps" min="1">
      </label>
      <label>
        重量(kg):
        <input type="number" formControlName="weight" min="0" step="0.5">
      </label>
      <button type="button" (click)="removeSet(i)">删除本组</button>
    </div>
  </div>

  <button type="button" (click)="addSet()" class="add-btn">+ 新增训练组</button>
</form>

扩展提示:如果后续需要支持多个训练动作录入(即workoutForm这个FormArray中存在多个动作FormGroup),只需要把getter中硬编码的0索引改为动态传入的动作下标即可,不需要改动核心逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:48:21