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

Angular响应式表单嵌套FormArray无报错但功能不生效问题求助

核心问题分析

你的嵌套FormArray功能异常的核心原因是没有正确关联外层info项和内层size数组的实例,具体问题如下:

  1. 原sizes getter逻辑完全错误:newInfo是每次调用都会返回全新FormGroup的getter,你通过sizes getter拿到的size数组,和页面上渲染的任意info项内部的size数组都不是同一个实例,所有针对sizes的操作都不会作用到页面绑定的表单上
  2. 模板内层循环数据源错误:内层size循环直接使用全局的sizes.controls,没有绑定到当前外层循环的info实例
  3. 操作方法没有关联对应外层项:addSizes/removeSizes没有指定操作哪个info下的size数组
  4. 删除逻辑不规范:直接操作FormArray的controls数组splice,没有使用Angular官方提供的removeAtAPI,容易出现表单状态不同步问题
  5. 循环索引重名:内外层循环都用i作为索引变量,会出现变量覆盖问题

修正后的实现代码

组件TypeScript代码修改

// 移除原来错误的 get sizes() 方法

// 修改addSizes,接收要操作的info项索引
addSizes(infoIndex: number) {
  const currentInfo = this.infos.at(infoIndex) as FormGroup;
  const currentSizeArr = currentInfo.get('size') as FormArray;
  currentSizeArr.push(this.newSize);
}

// 修改removeSizes,接收info项索引和要删除的size项索引
removeSizes(infoIndex: number, sizeIndex: number) {
  const currentInfo = this.infos.at(infoIndex) as FormGroup;
  const currentSizeArr = currentInfo.get('size') as FormArray;
  currentSizeArr.removeAt(sizeIndex);
  currentSizeArr.updateValueAndValidity();
}

// 修改removeInfos,用官方API删除
removeInfos(i: number) {
  this.infos.removeAt(i);
  this.infos.updateValueAndValidity();
}

原有其他代码无需修改。

模板HTML代码修改

<fieldset formArrayName="infoProduct" class="mb-3">
  <div class="row">
    <!-- 外层info循环索引改名为infoIndex,避免和内层索引冲突 -->
    <fieldset class="col-md-12" name="size" *ngFor="let info of infos.controls; let infoIndex = index"
      style="vertical-align: middle" [formGroupName]="infoIndex">

      <div formArrayName="size" class="mb-3">
        <!-- 内层size循环数据源改为当前info实例下的size数组,索引起名为sizeIndex -->
        <fieldset class="col-md-12" name="size" *ngFor="let zise of (info.get('size') as FormArray).controls; let sizeIndex = index"
          style="vertical-align: middle" [formGroupName]="sizeIndex">

          <div class="row">
            <div class="col-md-6 form-group">
              <input type="number" class="form-control" id="size" name="size" placeholder="Tamaño"
                formControlName="size" />
            </div>
          </div>
          <div class="col-md-6 form-group">
            <input type="number" class="form-control" id="stock" name="stock" placeholder="Stock"
              formControlName="stock" />
          </div>
          <div class="form-group">
            <a class="genric-btn info-border small" (click)="removeSizes(infoIndex, sizeIndex)">
              <mdb-icon fas icon="minus-circle"></mdb-icon>Eliminar
            </a>
          </div>
        </fieldset>
        <!-- 添加size时传入当前info的索引 -->
        <a class="genric-btn info-border small" (click)="addSizes(infoIndex)">
          <mdb-icon far icon="plus-square"></mdb-icon>Agregar
        </a>
      </div>

      <div class="form-group">
        <ckeditor [editor]="Editor" [config]="config" data="data" formControlName="description">
        </ckeditor>
      </div>
      <div class="row">
        <div class="col-md-6 form-group">
          <color-circle formControlName="color"></color-circle>
        </div>
        <div class="col-md-6 form-group">
          <input type="number" class="form-control" id="price" name="price" placeholder="Precio"
            formControlName="price" />
        </div>
      </div>
      <div class="form-group">
        <input type="file" class="form-control" id="image" name="image"
          (change)="cargarImagen($event, infoIndex)" />
      </div>
      <div class="form-group">
        <a class="genric-btn info-border small" (click)="removeInfos(infoIndex)">
          <mdb-icon fas icon="minus-circle"></mdb-icon>Eliminar
        </a>
      </div>
      <hr>
    </fieldset>
  </div>
  <a class="genric-btn info-border small" (click)="addInfos()">
    <mdb-icon far icon="plus-square"></mdb-icon>Agregar
  </a>
</fieldset>

修改后即可实现正常的嵌套FormArray增删功能,表单字段也会正常生成。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 01:36:04