Angular下拉菜单无法从嵌套数组对象加载城市选项如何解决
问题原因
- 你的
City数组第一层存储的是国家对象,而非直接的城市数据:每个国家对象下嵌套states州/省数组,每个州/省对象下才存储cities城市数组,直接遍历City数组取值city.cities自然拿不到对应数据 - 不同国家的州字段名不统一:印度的州字段为
name,美国的州字段为stname,遍历的时候会出现兼容问题 - 若使用
[(ngModel)]双向绑定,需确认AppModule中已导入FormsModule,否则绑定不会生效
解决方法
这边提供两种实现方案,你可以根据需求选择:
方案1:单下拉框展示所有城市
直接把所有层级的城市数据展平为一维数组,直接填充到下拉框:
1. 修改app.component.ts
import { Component, OnInit } from '@angular/core'; import { Title } from '@angular/platform-browser'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { constructor(private title: Title) {} selectedCity: string = "--Choose City--"; selected = "----"; // 展平后的城市数组 allCities: string[] = []; City: Array<any> = [ { name: 'India', states: [ { // 统一字段为stname,避免兼容问题 stname: 'Karnataka', cities: ['Bangalore', 'Gulbarga', 'Thumkur', 'Coorg' ] } , { stname: 'Andhrapradesh', cities: [ 'hyderabadh', 'x', 'Y', 'Z' ] } ] }, { name: 'USA', states: [ { stname: 'California', cities: [ 'Los Angeles', 'San Francisco' ] }, { stname: 'Texas', cities: [ 'Houston', 'Dallas' ] } ] }, ]; ngOnInit() { this.title.setTitle('Select through Dropdown'); // 展平所有城市 this.City.forEach(country => { country.states.forEach(state => { this.allCities.push(...state.cities) }) }) } changecities(event: any){ this.selected = event.target.value console.log(this.selectedCity); } }
2. 修改app.component.html
<div class="content" style="background-color: rgb(196, 195, 195);"> <h2 style="text-align: center;">Select Your Choices</h2> <div class="card-container" style="padding-bottom: 2em; padding-left: 10em;"> <label>City : </label> <select placeholder="City" [(ngModel)]="selectedCity" (change)="changecities($event)"> <option>--Choose City--</option> <option *ngFor="let city of allCities" [value]="city"> {{city}} </option> </select> </div> <p>You selected {{selected}}</p> </div> <router-outlet></router-outlet>
方案2:三级联动下拉(国家→州/省→城市)
更符合你现有数据结构的交互方式,选择对应国家后自动加载对应州,选择州后自动加载对应城市:
1. 修改app.component.ts
import { Component, OnInit } from '@angular/core'; import { Title } from '@angular/platform-browser'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { constructor(private title: Title) {} selectedCountry: any = null; selectedState: any = null; selectedCity: string = "--Choose City--"; selected = "----"; // 对应选中国家的州列表 stateList: any[] = []; // 对应选中州的城市列表 cityList: string[] = []; City: Array<any> = [ { name: 'India', states: [ { stname: 'Karnataka', cities: ['Bangalore', 'Gulbarga', 'Thumkur', 'Coorg' ] } , { stname: 'Andhrapradesh', cities: [ 'hyderabadh', 'x', 'Y', 'Z' ] } ] }, { name: 'USA', states: [ { stname: 'California', cities: [ 'Los Angeles', 'San Francisco' ] }, { stname: 'Texas', cities: [ 'Houston', 'Dallas' ] } ] }, ]; ngOnInit() { this.title.setTitle('Select through Dropdown'); } // 选择国家后加载对应州列表 onCountryChange() { this.stateList = this.selectedCountry.states; // 清空已选的州和城市 this.selectedState = null; this.cityList = []; this.selectedCity = "--Choose City--"; } // 选择州后加载对应城市列表 onStateChange() { this.cityList = this.selectedState.cities; this.selectedCity = "--Choose City--"; } changecities(event: any){ this.selected = event.target.value console.log(this.selectedCity); } }
2. 修改app.component.html
<div class="content" style="background-color: rgb(196, 195, 195);"> <h2 style="text-align: center;">Select Your Choices</h2> <div class="card-container" style="padding-bottom: 2em; padding-left: 10em;"> <!-- 国家选择下拉 --> <div style="margin-bottom: 10px;"> <label>Country : </label> <select [(ngModel)]="selectedCountry" (change)="onCountryChange()"> <option [ngValue]="null">--Choose Country--</option> <option *ngFor="let country of City" [ngValue]="country"> {{country.name}} </option> </select> </div> <!-- 州/省选择下拉 --> <div style="margin-bottom: 10px;"> <label>State : </label> <select [(ngModel)]="selectedState" (change)="onStateChange()" [disabled]="!selectedCountry"> <option [ngValue]="null">--Choose State--</option> <option *ngFor="let state of stateList" [ngValue]="state"> {{state.stname}} </option> </select> </div> <!-- 城市选择下拉 --> <div> <label>City : </label> <select placeholder="City" [(ngModel)]="selectedCity" (change)="changecities($event)" [disabled]="!selectedState"> <option>--Choose City--</option> <option *ngFor="let city of cityList" [value]="city"> {{city}} </option> </select> </div> </div> <p>You selected {{selected}}</p> </div> <router-outlet></router-outlet>
注意事项
请确保你的app.module.ts中已经导入FormsModule并加入imports数组,否则ngModel双向绑定不会生效:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; // 导入该模块 import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule, FormsModule // 加入到imports数组 ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
内容的提问来源于stack exchange,提问作者Chethan Yadav T L
相关产品推荐
相关产品推荐

