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

Angular 5 + Angular Material:选择国家后显示地区技术问询

Angular 5 表单实现「选国家自动加载对应地区」方案

我来给你一步步拆解这个需求的实现思路,结合你已有的FormArray表单结构来适配:


第一步:准备国家-地区映射数据

首先你需要一个数据源来存储国家和对应地区的关联关系,静态数据或者从后端API拉取都可以。先给你一个静态示例:

// 组件内定义:key用国家编码,value是对应地区列表
countryRegionMap: { [key: string]: string[] } = {
  "CN": ["北京", "上海", "广东", "浙江"],
  "US": ["加利福尼亚州", "纽约州", "德克萨斯州"],
  "JP": ["东京都", "大阪府", "神奈川县"]
};

// 用来存储每个地址项对应的地区列表(因为是FormArray,每个地址独立)
addressRegionList: string[][] = [];

第二步:改造addAddress()方法,监听国家选择变化

因为你的地址是动态添加的FormArray项,所以每个地址的country控件都需要单独监听变化,更新对应的地区列表:

addAddress() {
  // 先创建address子表单组
  const addressGroup = this.formBuilder.group({
    country: ['', [Validators.minLength(2)]],
    provinceType: ['', [Validators.minLength(2)]],
    // 你的其他address字段...
  });

  // 初始化当前地址项的地区列表为空,记录当前索引
  this.addressRegionList.push([]);
  const currentAddrIndex = this.addressRegionList.length - 1;

  // 监听当前address的country控件值变化
  addressGroup.get('country')?.valueChanges.subscribe(countryCode => {
    // 根据选中的国家编码获取对应地区,没有则为空数组
    this.addressRegionList[currentAddrIndex] = this.countryRegionMap[countryCode] || [];
    // 清空之前选中的地区,避免残留旧值
    addressGroup.get('provinceType')?.setValue('');

    // 可选:动态设置地区控件的验证规则(选国家后才必填)
    const provinceCtrl = addressGroup.get('provinceType');
    if (countryCode) {
      provinceCtrl?.setValidators([Validators.required, Validators.minLength(2)]);
    } else {
      provinceCtrl?.clearValidators();
    }
    provinceCtrl?.updateValueAndValidity();
  });

  // 组装addressWithProducts组并推入FormArray
  const addressWithProducts = this.formBuilder.group({
    address: addressGroup,
    // 你的其他products相关字段...
  });
  (this.form.get('addressesWithProducts') as FormArray).push(addressWithProducts);
}

第三步:模板层动态渲染地区选项

在模板里遍历FormArray的每个地址项,根据索引关联对应的地区列表:

<!-- 遍历所有动态添加的地址项 -->
<div *ngFor="let addrItem of form.get('addressesWithProducts').controls; let i = index">
  <div [formGroup]="addrItem.get('address')">
    <!-- 国家选择下拉框 -->
    <select formControlName="country">
      <option value="">请选择国家</option>
      <option *ngFor="let countryCode of Object.keys(countryRegionMap)" [value]="countryCode">
        {{ countryCode }} <!-- 这里可以替换成国家名称,比如再做一个countryName映射 -->
      </option>
    </select>

    <!-- 地区选择下拉框:只有选中国家且有对应地区时显示 -->
    <select 
      formControlName="provinceType"
      *ngIf="addressRegionList[i]?.length > 0"
    >
      <option value="">请选择地区</option>
      <option *ngFor="let region of addressRegionList[i]" [value]="region">
        {{ region }}
      </option>
    </select>
  </div>
</div>

<!-- 添加新地址按钮 -->
<button (click)="addAddress()">添加新地址</button>

额外优化:从API获取地区数据

如果你的地区数据需要从后端接口拉取,只需要把订阅里的静态数据替换成API请求即可:

addressGroup.get('country')?.valueChanges.subscribe(async countryCode => {
  if (!countryCode) {
    this.addressRegionList[currentAddrIndex] = [];
    return;
  }
  // 调用后端API获取地区列表(假设你的service有这个方法)
  const regions = await this.regionApiService.getRegionsByCountry(countryCode).toPromise();
  this.addressRegionList[currentAddrIndex] = regions;
  addressGroup.get('provinceType')?.setValue('');
});

内容的提问来源于stack exchange,提问作者quma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:31:50