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

如何通过国家名称而非iso2Code调用世界银行API展示国家信息

问题描述

我开发了一个Angular应用,通过服务调用世界银行API获取国家信息,展示搜索到的国家的名称、首都、地区、收入水平、经度和纬度。目前输入两位iso2Code可以成功展示这6项属性,但无法通过国家名称搜索,且世界银行API似乎不支持按国家名称直接查询。

我曾尝试将API返回的数据存入数组,再对比用户输入与数组中的属性值,但不确定如何选择并存储完整对象以展示所需属性,也不确定该方案是否正确。

现有代码

worldbank.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class WorldbankService {
  private apiUrl = 'http://api.worldbank.org/v2/country';

  constructor(private http: HttpClient) { }

  getCountryProperties(countryName: string): Observable<any> {
    const url = `${this.apiUrl}/${countryName}?format=json`;
    return this.http.get(url);
  }
}

country-info.component.ts

import { Component } from '@angular/core';
import { WorldbankService } from '../worldbank.service';

@Component({
  selector: 'app-country-info',
  templateUrl: './country-info.component.html',
  styleUrls: ['./country-info.component.css']
})
export class CountryInfoComponent {
  countryName = "";
  countryProperties: any = null;

  constructor(private worldbankService: WorldbankService) {}

  getCountryProperties() {
    this.worldbankService.getCountryProperties(this.countryName).subscribe(
      (data: any) => {
        this.countryProperties = data[1][0];
      }
    );
  }
}

country-info.component.html

<div class="right-column">
    <input type="text" [(ngModel)]="countryName" placeholder="Enter a country name" />
    <button (click)="getCountryProperties()">Enter</button>

    <ul class="properties-list" *ngIf="countryProperties">
        <li>Name: {{ countryProperties.name }}</li>
        <li>Capital: {{ countryProperties.capitalCity }}</li>
        <li>Region: {{ countryProperties.region.value }}</li>
        <li>Income Level: {{ countryProperties.incomeLevel.value }}</li>
        <li>Latitude: {{ countryProperties.latitude }}</li>
        <li>Longitude: {{ countryProperties.longitude }}</li>
    </ul>
</div>

解决方案

世界银行API确实不支持直接通过国家名称精确/模糊查询,可行方案是先获取所有国家的完整列表并缓存,再在前端根据用户输入的名称做匹配。这样既减少重复API请求,又能实现名称搜索功能。

1. 修改WorldbankService,添加缓存与搜索逻辑

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { map, tap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class WorldbankService {
  private apiUrl = 'http://api.worldbank.org/v2/country';
  private allCountriesCache: any[] | null = null; // 缓存所有国家数据

  constructor(private http: HttpClient) { }

  // 获取所有国家列表(带缓存,避免重复请求)
  getAllCountries(): Observable<any[]> {
    if (this.allCountriesCache) {
      return of(this.allCountriesCache);
    }

    // 加per_page=300确保获取全部国家(API默认只返回50条)
    const url = `${this.apiUrl}?format=json&per_page=300`;
    return this.http.get<any>(url).pipe(
      map(data => data[1]), // 提取国家数据数组
      tap(countries => this.allCountriesCache = countries) // 缓存数据
    );
  }

  // 根据名称模糊搜索国家
  searchCountryByName(name: string): Observable<any[]> {
    return this.getAllCountries().pipe(
      map(countries => {
        const lowerCaseInput = name.toLowerCase().trim();
        return countries.filter(country => 
          country.name.toLowerCase().includes(lowerCaseInput)
          || (country.capitalCity && country.capitalCity.toLowerCase().includes(lowerCaseInput)) // 可选:支持按首都搜索
        );
      })
    );
  }

  // 保留原有的按iso2Code查询方法
  getCountryByCode(code: string): Observable<any> {
    const url = `${this.apiUrl}/${code}?format=json`;
    return this.http.get<any>(url).pipe(
      map(data => data[1][0])
    );
  }
}

2. 修改CountryInfoComponent,适配双模式搜索

import { Component } from '@angular/core';
import { WorldbankService } from '../worldbank.service';

@Component({
  selector: 'app-country-info',
  templateUrl: './country-info.component.html',
  styleUrls: ['./country-info.component.css']
})
export class CountryInfoComponent {
  inputValue = "";
  countryProperties: any = null;
  searchResults: any[] = []; // 存储搜索结果列表

  constructor(private worldbankService: WorldbankService) {}

  searchCountry() {
    const input = this.inputValue.trim();
    if (!input) {
      this.countryProperties = null;
      this.searchResults = [];
      return;
    }

    // 判断输入是否是两位iso2Code(大写字母)
    if (/^[A-Z]{2}$/.test(input.toUpperCase())) {
      this.worldbankService.getCountryByCode(input.toUpperCase()).subscribe(
        country => {
          this.countryProperties = country;
          this.searchResults = [];
        },
        () => {
          this.countryProperties = null;
          this.searchResults = [];
          alert('未找到对应国家');
        }
      );
    } else {
      // 按名称搜索
      this.worldbankService.searchCountryByName(input).subscribe(
        results => {
          this.searchResults = results;
          this.countryProperties = null;
          // 如果只有一个匹配结果,自动展示详情
          if (results.length === 1) {
            this.countryProperties = results[0];
            this.searchResults = [];
          }
        }
      );
    }
  }

  // 从搜索结果中选择单个国家
  selectCountry(country: any) {
    this.countryProperties = country;
    this.searchResults = [];
    this.inputValue = country.name;
  }
}

3. 修改模板,支持展示搜索结果列表

<div class="right-column">
    <input type="text" [(ngModel)]="inputValue" placeholder="输入国家名称或两位代码" />
    <button (click)="searchCountry()">搜索</button>

    <!-- 搜索结果列表 -->
    <ul class="search-results" *ngIf="searchResults.length > 0">
        <li *ngFor="let country of searchResults" (click)="selectCountry(country)">
            {{ country.name }} ({{ country.iso2Code }})
        </li>
    </ul>

    <!-- 国家详情 -->
    <ul class="properties-list" *ngIf="countryProperties">
        <li>名称: {{ countryProperties.name }}</li>
        <li>首都: {{ countryProperties.capitalCity || '无' }}</li>
        <li>地区: {{ countryProperties.region.value }}</li>
        <li>收入水平: {{ countryProperties.incomeLevel.value }}</li>
        <li>纬度: {{ countryProperties.latitude }}</li>
        <li>经度: {{ countryProperties.longitude }}</li>
    </ul>
</div>

核心要点

  • 缓存机制:第一次获取所有国家数据后会缓存,后续搜索直接用本地数据,减少API请求次数。
  • 双模式搜索:自动识别输入是两位代码还是名称,分别走不同的查询逻辑。
  • 模糊匹配:搜索时忽略大小写,支持匹配国家名称,还可扩展匹配首都等字段。
  • 结果交互:多结果时展示列表,点击列表项可查看详情;单结果时自动展示详情。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:45:15