Angular中如何展示formControlName(moduleGroupName)的去重值
Angular 中展示去重后 moduleGroupName 表单值的实现方案
直接遍历 FormArray 全量值渲染的写法,会导致同属一个模块组的每一行都重复显示moduleGroupName,要实现去重展示有两种常用方案,可根据布局需求选择:
方案一:按模块组重构渲染结构(推荐)
核心逻辑是先在TS侧对所有表单项按moduleGroupName分组去重,模板层每个模块组只渲染一次组名输入框,组下挂载对应子模块的权限项,结构清晰易维护。
1. TS侧新增分组去重逻辑
原有BuildFormDynamic方法无需修改,新增一个getter获取去重后的分组数据:
import { FormArray } from '@angular/forms'; // 获取去重后的模块组,关联组内所有表单项的索引 get uniqueModuleGroups() { const permissionArray = this.permissionForm.get('permissionForm') as FormArray; const groupMap = new Map<string, number[]>(); permissionArray.controls.forEach((control, index) => { const groupName = control.get('moduleGroupName').value; if (groupMap.has(groupName)) { groupMap.get(groupName).push(index); } else { groupMap.set(groupName, [index]); } }); return Array.from(groupMap.entries()).map(([groupName, itemIndexes]) => ({ groupName, itemIndexes })); }
2. 改造HTML模板
不要直接遍历permissionForm.value(这种写法无法实时响应表单状态更新),改为遍历去重后的分组数据:
<div formArrayName="permissionForm"> <div *ngFor="let group of uniqueModuleGroups" class="module-group"> <!-- 每个模块组仅渲染一次moduleGroupName输入框,绑定组内第一个控件即可 --> <input type="text" readonly [formControl]="permissionForm.get('permissionForm').at(group.itemIndexes[0]).get('moduleGroupName')" class="group-name" /> <!-- 遍历组内所有子权限项,渲染子模块行 --> <div *ngFor="let idx of group.itemIndexes" [formGroupName]="idx" class="sub-module-row"> <!-- 此处保留原有子模块字段,不需要再渲染moduleGroupName --> <span>{{ permissionForm.get('permissionForm').at(idx).get('subModules').value }}</span> <label><input type="checkbox" formControlName="view" /> 查看</label> <label><input type="checkbox" formControlName="add" /> 新增</label> <label><input type="checkbox" formControlName="edit" /> 编辑</label> <label><input type="checkbox" formControlName="delete" /> 删除</label> </div> </div> </div>
提示:因为
moduleGroupName是只读属性,绑定组内第一个控件完全可以满足展示需求;如果后续需要支持编辑组名,只需给第一个控件加valueChanges监听,同步修改同组所有项的moduleGroupName值即可保证数据一致。
方案二:轻量改造(不改动原有DOM结构)
如果不想调整现有布局,只是想把重复的组名输入框隐藏,仅保留同组第一个项显示,可以用索引判断的方式实现:
1. TS侧新增判断方法
// 判断当前索引是否为对应moduleGroupName第一次出现的位置 isFirstGroupItem(index: number): boolean { const permissionArray = this.permissionForm.get('permissionForm') as FormArray; const currentGroup = permissionArray.at(index).get('moduleGroupName').value; for (let i = 0; i < index; i++) { if (permissionArray.at(i).get('moduleGroupName').value === currentGroup) { return false; } } return true; }
2. 模板加显示判断
<div formArrayName="permissionForm"> <!-- 注意:遍历controls而非value,保证视图实时同步表单状态 --> <div *ngFor="let item of permissionForm.get('permissionForm').controls; let i=index" [formGroupName]="i"> <!-- 仅同组第一个项显示组名输入框,其余重复项隐藏 --> <input type="text" readonly formControlName="moduleGroupName" *ngIf="isFirstGroupItem(i)" /> <!-- 原有其他控件保持不变 --> <input type="checkbox" formControlName="view" /> <input type="checkbox" formControlName="add" /> <input type="checkbox" formControlName="edit" /> <input type="checkbox" formControlName="delete" /> </div> </div>
内容的提问来源于stack exchange,提问作者Ayushi Gajpal
相关产品推荐
相关产品推荐

