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

Angular嵌套FormArray内层FormControl无法获取选中值问题

问题原因

两个核心错误导致内层表单控件值无法同步:

  • 数据源绑定错误:给mat-table传入的是secondDataArray的值快照(即调用.value返回的普通对象数组),而非FormArray表单实例本身,渲染层和表单模型完全断开,用户输入无法回写到FormControl。
  • 表单层级缺失:模板中直接在单元格内使用formControlName="qtd",既没有在外层循环绑定外层FormGroup的上下文,也没有给表格行绑定对应索引的内层FormGroup,Angular表单无法定位qtd控件所属的父容器,值自然无法注册。
修复方案

1. 调整组件类代码,新增获取内层FormArray的辅助方法

避免模板中写复杂的类型转换,同时保证拿到的是表单实例而非值快照:

// 获取指定外层行索引对应的内层secondDataArray FormArray实例
getInnerFormArray(outerIndex: number): UntypedFormArray {
  return this.firstGroup.get(['dataArray', outerIndex, 'secondDataArray']) as UntypedFormArray;
}

2. 修正模板表单层级与数据源绑定

重点修正四个位置:

  • 外层循环渲染FormArray行时,必须绑定formArrayName="dataArray"和对应索引的[formGroupName]="i",建立外层表单上下文
  • mat-table的[dataSource]直接绑定FormArray实例,不要调用.value取快照
  • 内层表格的每一行通过索引绑定对应的内层FormGroup,给qtd控件提供正确的父表单上下文
  • 删除mat-select上多余的name="qtd"属性,响应式表单不需要模板驱动表单的name标识,避免冲突

修正后的模板代码示例:

<!-- 根表单绑定 -->
<div [formGroup]="firstGroup">
  <!-- 外层FormArray绑定 -->
  <div formArrayName="dataArray">
    <!-- 循环外层每一个FormGroup -->
    <div *ngFor="let outerItem of dataArray.controls; let i = index" [formGroupName]="i">
      <!-- 外层必填项chooseOption1 -->
      <mat-form-field appearance="outline">
        <mat-select formControlName="chooseOption1" placeholder="选择选项1">
          <!-- 自行补充选项内容 -->
        </mat-select>
      </mat-form-field>

      <!-- 内层mat-table修正 -->
      <table
        mat-table
        [dataSource]="getInnerFormArray(i)"
        formArrayName="secondDataArray"
        class="mat-elevation-z8"
      >
        <ng-container matColumnDef="qtd">
          <th mat-header-cell *matHeaderCellDef>QTD</th>
          <td mat-cell *matCellDef="let row; let innerIdx = index">
            <!-- 绑定当前内层行的FormGroup -->
            <div [formGroupName]="innerIdx">
              <mat-form-field appearance="outline">
                <mat-select formControlName="qtd" placeholder="选择QTD">
                  <mat-option *ngFor="let ob of exampleData" [value]="ob">
                    {{ ob.symbol }}
                  </mat-option>
                </mat-select>
              </mat-form-field>
            </div>
          </td>
        </ng-container>

        <tr mat-header-row *matHeaderRowDef="displayColumns"></tr>
        <tr mat-row *matRowDef="let row; columns: displayColumns"></tr>
      </table>

      <button type="button" (click)="addInnerLine(i)">添加内层行</button>
    </div>
  </div>
  <button type="button" (click)="addOuterLine()">添加外层行</button>
</div>

验证方式

修改完成后选择qtd下拉选项,打印firstGroup.value即可看到dataArray下每一项的secondDataArray中,对应行的qtd字段已经正确同步选中的值,表单校验也能正常生效。


内容的提问来源于stack exchange,提问作者T.Aguiar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:27:25