You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 08:00:01