Angular FormArray添加控件时使用自定义名称而非数字索引的问题
问题根因
FormArray原生设计就是以数字索引作为控件标识,本身不支持自定义控件名,你需要的自定义键值对结构的控件集合,应该使用FormGroup承载,而非FormArray。
修改实现步骤
1. 调整表单声明
将Features字段的类型从FormArray替换为空FormGroup,用于后续添加自定义命名的控件:
public addStorageFacility(): FormGroup { return this.formBuilder.group({ Features: this.formBuilder.group({}) }) }
2. 替换控件添加逻辑
不再使用push方法往FormArray里塞控件,改用addControl方法往Features对应的FormGroup里添加自定义名称的控件,初始值设为需求里的false:
const featureList = this.featureList; // 修正控件类型为FormGroup const featureFormGroup = this.storageFacilityDetailsForm.controls['Features'] as FormGroup; featureList.forEach((feature) => { // 第一个参数传入自定义控件名(对应MyCars/YourCars这类键),第二个参数传入控件实例 // 注意:如果你的自定义名称存在feature的其他字段,把feature.key替换成对应字段即可 featureFormGroup.addControl(feature.key, this.formBuilder.control(false)); })
3. 修正控件获取方法
FormGroup的controls是键值对对象,需要转成可遍历的数组供模板渲染:
public getFeaturesDetailsControls() { const featureGroup = this.storageFacilityDetailsForm.get('Features') as FormGroup; return Object.keys(featureGroup.controls).map(controlName => { return { name: controlName, instance: featureGroup.get(controlName) } }) }
4. 调整模板绑定逻辑
移除原来的formArrayName绑定,改用formGroupName绑定Features节点,遍历后用自定义name作为表单控件名:
<div class="row g-0 features"> <label>{{'facility.features' | translate}}</label> <div formGroupName="Features"> <div *ngFor="let unit of getFeaturesDetailsControls()" class="col featureslist"> <mat-checkbox [formControlName]="unit.name"> {{unit.name}} </mat-checkbox> </div> </div> </div>
最终输出结构
修改完成后,Features字段的表单值结构完全匹配需求:
Features: { MyCars: false, YourCars: false, ThereCar: false, WhereCar: false, }
后续可以直接通过this.storageFacilityDetailsForm.get('Features.MyCars')的方式精准获取对应控件实例,也能直接拿到符合结构的表单提交值。
内容的提问来源于stack exchange,提问作者Tushar Maheshwari
相关产品推荐
相关产品推荐

