Angular FormArray按国家分组构造城市列表表单及模板实现问题
问题原因及修复方案
现有表单结构的错误点
citiesList当前定义为FormArray,你往里面插入的是每个仅包含单个国家key的FormGroup,FormArray只能通过索引下标访问,不能直接通过国家名作为key获取对应控件,这是getCountryFormArray返回null的核心原因addCity方法中使用了未定义的prefix、nr变量,应该使用传入的country和city参数
修正后的TS代码
import { FormArray, FormControl, FormGroup, FormBuilder } from '@angular/forms'; // 调整表单结构,citiesList改用FormGroup存储,方便按国家名快速查找对应分组 form = this.fb.group({ newEntry: [], cityToFind: [], citiesList: this.fb.group({}), // key为国家名,value为对应城市的FormArray }); get citiesListGroup(): FormGroup { return this.form.get('citiesList') as FormGroup; } get searchInput(): FormControl { return this.form.get('cityToFind') as FormControl; } get newEntryFormControl(): FormControl { return this.form.get('newEntry') as FormControl; } getCountryFormArray(country: string): FormArray | null { return this.citiesListGroup.get(country) as FormArray || null; } addCountrySection(country: string): void { // 避免重复添加同一个国家分组 if (!this.citiesListGroup.contains(country)) { this.citiesListGroup.addControl(country, this.fb.array([])); } } addCity(country: string, city: string): void { // 不存在对应国家时自动创建分组 this.addCountrySection(country); const countryCities = this.getCountryFormArray(country); if (countryCities) { countryCities.push(this.fb.control(city)); } } // 逗号分隔输入的解析逻辑 handleAddNewEntry(): void { const inputVal = this.newEntryFormControl.value?.trim(); if (!inputVal) return; const [country, city] = inputVal.split(',').map(item => item.trim()); if (country && city) { this.addCity(country, city); this.newEntryFormControl.reset(); } } ngOnInit(): void { this.addCountrySection('USA'); this.addCountrySection('DE'); this.addCity('DE', 'Berlin'); console.log(this.getCountryFormArray('DE')); // 可正常获取对应FormArray }
模板编写示例
<!-- 新增国家城市输入区 --> <div> <input type="text" [formControl]="newEntryFormControl" placeholder="输入格式:国家,城市 例:中国,上海"> <button (click)="handleAddNewEntry()">添加到列表</button> </div> <!-- 城市搜索框 --> <div> <input type="text" [formControl]="searchInput" placeholder="搜索城市"> </div> <!-- 国家城市列表展示区 --> <div formGroupName="citiesList"> <!-- 遍历所有国家分组 --> <div *ngFor="let country of citiesListGroup.controls | keyvalue"> <h3>{{ country.key }}</h3> <ul [formArrayName]="country.key"> <!-- 遍历当前国家下的所有城市 --> <li *ngFor="let cityControl of getCountryFormArray(country.key).controls; let i = index"> <span>{{ cityControl.value }}</span> <!-- 可选:城市删除按钮 --> <button (click)="getCountryFormArray(country.key).removeAt(i)">删除</button> </li> </ul> </div> </div>
内容的提问来源于stack exchange,提问作者Motassem Jalal
相关产品推荐
相关产品推荐

