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

如何在Angular中从JSON内的列表提取城市值并正确渲染至下拉选择器

解决Angular下拉选择器中嵌套城市数组的展开问题

你遇到的核心问题是当前的*ngFor在遍历每个部门对象,然后直接输出该部门的整个城市数组,Angular会自动把数组转换成逗号分隔的字符串作为单个选项。要实现每个城市单独成为下拉选项,我们需要把嵌套的城市数组展开,同时先修复代码里的一个变量冲突bug:


第一步:修复变量名冲突

你的组件里存在变量名重复问题:public cities: City[] = []; 和构造函数里的 public cities: CitiesService; 重名了,这会导致服务实例被覆盖,后续调用服务方法大概率出错。先修改组件代码:

import { Component, OnInit } from '@angular/core';
import { CitiesService } from 'src/app/services/cities.service';

// 建议把接口名改成Department,更贴合数据结构的实际含义
interface Department {
  department: string;
  cities: string[];
}

@Component({
  selector: 'app-nueva-organizacion',
  templateUrl: './nueva-organizacion.component.html',
  styleUrls: ['./nueva-organizacion.component.css'],
})
export class NuevaOrganizacionComponent implements OnInit {
  // 存储所有部门数据
  public departments: Department[] = [];
  // 如果用方案二,这里新增存储所有城市的一维数组
  // public allCities: string[] = [];

  constructor(
    // 把服务实例的变量名改成cityService,避免和数据变量冲突
    private cityService: CitiesService,
  ) {}

  ngOnInit(): void {
    this.cityService
      .getJSON(
        'https://raw.githubusercontent.com/marcovega/colombia-json/master/colombia.min.json'
      )
      .subscribe((res: any) => {
        this.departments = res;
        // 如果用方案二,在这里添加合并城市的逻辑
        // this.allCities = res.flatMap(dept => dept.cities);
      });
  }
}

方案一:模板中使用嵌套*ngFor(无需修改组件逻辑)

直接在模板里用<ng-container>遍历每个部门,再嵌套遍历该部门的城市数组,这样每个城市会生成单独的<option>标签:

<div class="form-input">
  <select id="city" class="custom-select">
    <option selected>Choose one...</option>
    <!-- 先遍历每个部门 -->
    <ng-container *ngFor="let dept of departments">
      <!-- 再遍历当前部门下的所有城市 -->
      <option *ngFor="let city of dept.cities">
        {{ city }}
      </option>
    </ng-container>
  </select>
</div>

方案二:组件中预处理数据(适合需复用城市列表的场景)

如果后续业务中还需要单独使用所有城市的列表,可以在组件里把所有部门的城市合并成一个一维数组,然后模板直接遍历这个数组:

在组件的subscribe回调里添加合并逻辑:

this.cityService.getJSON(url).subscribe((res: any) => {
  this.departments = res;
  // 使用flatMap把嵌套的cities数组展开成一维数组
  this.allCities = res.flatMap(dept => dept.cities);
});

然后模板简化为:

<div class="form-input">
  <select id="city" class="custom-select">
    <option selected>Choose one...</option>
    <option *ngFor="let city of allCities">
      {{ city }}
    </option>
  </select>
</div>

两种方式都能实现你想要的下拉效果:如果只是单纯展示城市,方案一更直接;如果后续有复用城市列表的需求,方案二更灵活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 10:39:07