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

Angular 5中用ngFor在单个下拉框实现州与城市分组展示

嘿,我来帮你搞定这个Angular 5的select分组展示问题!其实核心是要用到原生HTML的<optgroup>标签来实现州-城市的分组结构,配合Angular的*ngFor就能轻松达成需求。

第一步:处理数据源(可选但推荐)

先看你提供的JSON,城市数组里每个元素是单个键值对的对象(比如{"city1": "city1"}),直接用的话模板里会有点麻烦,建议在组件里先把它转换成更易用的格式:

// 组件.ts文件里的代码
import { Component } from '@angular/core';

@Component({
  selector: 'app-location-select',
  templateUrl: './location-select.component.html'
})
export class LocationSelectComponent {
  // 原始数据源
  rawLocationData = { 
    "location": [
      { 
        "state": "state1", 
        "cities": [{ "city1": "city1" }, { "city2": "city2" } ] 
      }, 
      { 
        "state": "state2", 
        "cities": [{ "city1": "city1" }, { "city2": "city2" }, { "city3": "city3" } ] 
      } 
    ] 
  };

  // 处理后的数据源:把城市转换成名称数组
  processedLocations = this.rawLocationData.location.map(stateItem => ({
    stateName: stateItem.state,
    cities: stateItem.cities.map(cityObj => Object.values(cityObj)[0])
  }));
}

第二步:模板里实现分组下拉框

在组件的HTML模板中,用<optgroup>作为州的分组容器,内部嵌套<option>展示城市:

<!-- 组件.html文件里的代码 -->
<select>
  <!-- 遍历每个州,生成分组 -->
  <optgroup *ngFor="let stateGroup of processedLocations" label="{{ stateGroup.stateName }}">
    <!-- 遍历当前州下的所有城市,生成选项 -->
    <option *ngFor="let city of stateGroup.cities" value="{{ city }}">
      {{ city }}
    </option>
  </optgroup>
</select>

如果你不想在组件里处理数据(直接用原始数据源)

也可以直接在模板里处理城市对象,不过代码会稍微繁琐一点:

<select>
  <optgroup *ngFor="let stateItem of rawLocationData.location" label="{{ stateItem.state }}">
    <option *ngFor="let cityObj of stateItem.cities" value="{{ Object.values(cityObj)[0] }}">
      {{ Object.values(cityObj)[0] }}
    </option>
  </optgroup>
</select>

进阶:用管道优化模板代码

如果觉得模板里写Object.values不够优雅,可以自定义一个管道来提取城市名称:

// extract-city-name.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'cityName' })
export class CityNamePipe implements PipeTransform {
  transform(cityObj: any): string {
    // 提取对象里的唯一值作为城市名称
    return Object.values(cityObj)[0];
  }
}

记得在你的模块里声明这个管道,然后模板里就可以这样用:

<select>
  <optgroup *ngFor="let stateItem of rawLocationData.location" label="{{ stateItem.state }}">
    <option *ngFor="let cityObj of stateItem.cities" value="{{ cityObj | cityName }}">
      {{ cityObj | cityName }}
    </option>
  </optgroup>
</select>

这样写出来的下拉框会把每个州作为分组标题,下面列出对应的城市,完全符合你要的非多选分组展示效果~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:37:51