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

Angular提交表单时如何传递FormArray中roleMenu的所有数据?

解决Angular表单提交时仅传递formArray第一条数据的问题

问题原因

你的代码存在两个核心问题:

  1. formArray初始化不足:roleMenu表单数组只初始化了1个表单组,但你需要为每个selectedMenuData的条目创建对应表单组,否则多余的菜单行无法绑定到独立的表单控件上。
  2. HTML循环结构错误:外层循环遍历formArray的控件,内层又遍历selectedMenuData,导致所有菜单行的checkbox都绑定到同一个formGroup(索引0),最终只有第一条数据被提交。

解决方案

1. 修正TypeScript代码:动态生成formArray表单组

封装创建单个菜单权限表单组的方法,在获取到selectedMenuData后,根据数据量动态填充roleMenu表单数组。

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

postForm: FormGroup;
selectedMenuData: any[];

constructor(private formBuilder: FormBuilder) {}

ngOnInit(): void {
  this.postForm = this.formBuilder.group({
    selectedMenuId: [[]],
    roleMenu: this.formBuilder.array([]) // 初始化为空数组
  });

  // 假设此处获取菜单数据(实际替换为API请求或数据加载逻辑)
  this.selectedMenuData = [
    { menuId: 1, menuname: "菜单1" },
    { menuId: 2, menuname: "菜单2" }
  ];
  this.initRoleMenuFormArray();
}

// 创建单个菜单权限表单组
private createRoleMenuGroup(menuId: number): FormGroup {
  return this.formBuilder.group({
    menu: this.formBuilder.group({
      menuId: [menuId]
    }),
    readAccess: [false],
    writeAccess: [false]
  });
}

// 初始化roleMenu表单数组
private initRoleMenuFormArray(): void {
  const roleMenuArray = this.postForm.get('roleMenu') as FormArray;
  roleMenuArray.clear();
  this.selectedMenuData.forEach(menu => {
    roleMenuArray.push(this.createRoleMenuGroup(menu.menuId));
  });
}

onSubmit(){
  console.log(this.postForm.value);
}

2. 修正HTML代码:匹配表单数组与菜单数据的循环结构

调整循环层级,让每个菜单行直接对应formArray中的一个表单组,避免嵌套循环导致的绑定错误。

<div formArrayName="roleMenu">
  <table matSort class="table --table-responsive table-bordered table-border-new">
    <thead class="t-head">
      <tr>
        <th class="text-center col-form-label">Menu Name</th>
        <th class="text-center col-form-label">Read Access</th>
        <th class="text-center col-form-label">Write Access</th>
      </tr>
    </thead>
    <tbody>
      <!-- 同步遍历菜单数据与表单数组控件,确保索引对应 -->
      <tr 
        *ngFor="let menu of selectedMenuData; let i=index" 
        [formGroupName]="i"
      >
        <td class="text-center">{{ menu.menuname }}</td>
        <td class="text-center">
          <mat-checkbox formControlName="readAccess"></mat-checkbox>
        </td>
        <td class="text-center">
          <mat-checkbox formControlName="writeAccess"></mat-checkbox>
        </td>
      </tr>
    </tbody>
  </table>
</div>

关键说明

  • 确保selectedMenuData的长度与roleMenu表单数组的长度完全一致,每个菜单对应独立的表单控件。
  • 通过formGroupName="i"将每一行绑定到表单数组对应索引的表单组,保证每个checkbox的状态能正确映射到对应表单数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 06:24:55