Angular嵌套FormArray报错:Cannot find control '0-1'及权限计数求助
问题解答
一、错误原因及修复
你的错误核心是FormControlName的绑定不符合FormArray的结构:
- 每个角色的权限是一个
FormArray(rights),FormArray的控件按索引顺序存储,并非用i + '-' + right.id这类自定义名称关联。 - HTML中你绑定了
[formControlName]="i + '-' + right.id",但表单结构里不存在该名称的控件,因此报错找不到控制项。
修复步骤:
修正HTML复选框绑定逻辑:
需先通过formArrayName="rights"声明当前角色的权限是FormArray,再用索引j绑定对应控件。修正后的HTML代码:<form [formGroup]="roleRightsForm"> <table> <thead> <tr> <th></th> <th *ngFor="let right of rights">{{ right.name }}</th> </tr> </thead> <tbody> <tr *ngFor="let roleGroup of getRoles; let i = index" [formGroup]="roleGroup"> <td>{{ roleGroup.value.role.name }}</td> <!-- 声明当前角色的权限集合为FormArray --> <td *ngFor="let right of rights; let j = index" formArrayName="rights"> <!-- 绑定FormArray的索引位置 --> <input type="checkbox" [formControlName]="j"> </td> </tr> </tbody> <!-- 新增合计行 --> <tfoot> <tr> <td>合计</td> <td *ngFor="let right of rights; let j = index"> {{ getRightCount(j) }} </td> </tr> </tfoot> </table> </form>初始化表单:
在组件的ngOnInit钩子中调用initRoles(),确保表单在组件加载时初始化:ngOnInit(): void { this.initRoles(); }
二、列选中权限总数的最优实现
不需要额外在roleFormGroup中添加count属性,直接通过动态计算即可,无需手动维护变更事件,Angular会自动响应表单值变化更新统计结果。
实现方法:
在组件中添加统计方法,传入权限索引j,遍历所有角色的对应权限控件,统计选中数量:
getRightCount(rightIndex: number): number { const rolesArray = this.roleRightsForm.get('roles') as FormArray; return rolesArray.controls.reduce((total, roleGroup) => { const rightsArray = roleGroup.get('rights') as FormArray; const isChecked = rightsArray.controls[rightIndex].value; return total + (isChecked ? 1 : 0); }, 0); }
HTML的合计行直接调用该方法,即可实时显示每列的选中总数。
适配jQuery背景的补充说明
Angular表单是数据驱动的,和jQuery直接操作DOM的思路差异较大:
- 不要通过DOM操作修改或统计表单值,应通过FormGroup/FormArray的API访问和修改数据。
- 表单值变化时,Angular的变更检测会自动更新视图,无需手动绑定事件更新统计值。
内容的提问来源于stack exchange,提问作者Adam.M
相关产品推荐
相关产品推荐

