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
相关产品推荐
相关产品推荐

