Angular 9:如何为数组每个索引仅生成一个下拉列表表单控件?
我帮你找到了问题的核心所在!咱们一步步来解决这个“生成过多下拉框”的问题:
问题根源
你当前的表单创建逻辑出了问题:当你把odkDataIndexes里的字符串(比如'id')直接传给this.fb.group(values)时,Angular的FormGroup会把字符串当成键值对集合来解析——它会把字符串拆分成单个字符,每个字符作为一个FormControl的键。举个例子,如果索引是长度为16的字符串,就会生成16个以单个字符为键的控件,自然就渲染出了16个下拉框。
解决方案
我们需要调整表单数组的创建逻辑,让每个索引对应单个专属的FormControl,再把这些控件包装成FormGroup适配你的模板结构:
1. 修改TypeScript创建表单的方法
更新createIndexesForm,确保每个索引只生成一个控件:
createIndexesForm(extractedIndexesArray): void { this.indexesForm = this.fb.group({ mappingFieldItems: this.fb.array( extractedIndexesArray.map(index => { // 为每个索引创建仅包含该索引作为键的FormGroup return this.fb.group({ [index]: [''] // 初始化空值,可根据需求设置默认值 }); }) ) }); }
generateMappingFields方法可以保持原样,但确保逻辑触发正确:
async generateMappingFields() { this.showFields = false; if (this.odkDataIndexes.length > 0) { this.createIndexesForm(this.odkDataIndexes); } this.showFields = true; }
2. 调整HTML模板绑定逻辑
修改模板,精准绑定到每个索引对应的控件,避免遍历错误生成的字符键控件:
<div *ngIf="showFields"> <mat-spinner *ngIf="!indexesForm" value="50" class="setSpinnerOnTop" diameter="75" [color]="medair-color"></mat-spinner> <div [formGroup]="indexesForm" *ngIf="indexesForm"> <div formArrayName="mappingFieldItems"> <div *ngFor="let fg of indexesForm.get('mappingFieldItems').controls; let i = index" [formGroup]="fg"> <!-- 直接用当前索引作为formControlName,绑定专属控件 --> <mat-form-field class="formFieldWidth" color="warn" appearance="fill"> <mat-label>{{odkDataIndexes[i]}}</mat-label> <mat-select [formControlName]="odkDataIndexes[i]"> <mat-option (click)="getName(odkDataIndexes[i], de.id, fg)" *ngFor="let de of dataElementsDetails" [value]="de.id"> {{de.code}} </mat-option> </mat-select> </mat-form-field> </div> </div> </div> </div>
关键说明
- 用
[index]: ['']的语法,为每个索引创建了唯一对应的FormControl,确保每个FormGroup里只有一个有效控件。 - 模板中直接通过
odkDataIndexes[i]绑定formControlName,精准对应到目标控件,避免了遍历错误生成的字符键控件。 - 调整了
getName方法的参数,现在传递的是正确的索引名称,而非之前错误的控件值。
这样修改后,每个索引就只会对应一个下拉框,完全符合你的需求啦!
内容的提问来源于stack exchange,提问作者alim1990
相关产品推荐
相关产品推荐

