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

Angular跨组件数据传递:点击城市切换天气API数据方案

Angular城市天气切换实现方案

问题描述

学习Angular时遇到组件间数据传递与动态加载数据的问题:首页有四个城市(伦敦、纽约、东京、悉尼),点击任意城市后跳转到天气数据组件,需根据点击的城市动态修改WeatherService中API请求的经纬度,展示对应城市的天气数据(温度、湿度等),当前数据固定为伦敦的默认值。

实现步骤

1. 首页组件:传递城市经纬度参数

修改首页组件HTML,给每个城市的路由链接添加对应经纬度的查询参数:

<div class="container">
  <div class="grid">
    <a routerLink="/weather-data" [queryParams]="{lat: '51.51', lon: '-0.13'}">
      <h3>London</h3>
    </a>
    <a routerLink="/weather-data" [queryParams]="{lat: '40.71', lon: '-74.01'}">
      <h3>New York</h3>
    </a>
    <a routerLink="/weather-data" [queryParams]="{lat: '35.67', lon: '139.65'}">
      <h3>Tokyo</h3>
    </a>
    <a routerLink="/weather-data" [queryParams]="{lat: '-33.87', lon: '151.21'}">
      <h3>Sydney</h3>
    </a>  
  </div>
</div>

2. 天气数据组件:接收参数并加载对应数据

修改WeatherDataComponent,注入路由服务监听参数变化,动态请求对应城市数据:

import { ActivatedRoute, ParamMap } from '@angular/router';
// ...保留原有导入

export class WeatherDataComponent implements OnInit, OnDestroy {
  // ...保留原有属性
  private currentLat: string = '51.51';
  private currentLon: string = '-0.13';

  constructor(
    private weatherService: WeatherService,
    public datePipe: DatePipe,
    private route: ActivatedRoute // 新增路由注入
  ) {
    // ...保留原有构造函数内容
  }

  ngOnInit(): void {
    this.weatherDataLoading = true;
    // 监听路由参数变化,支持组件复用场景下的城市切换
    this.route.queryParamMap.pipe(
      takeUntil(this.componentDestroyed$)
    ).subscribe((paramMap: ParamMap) => {
      const lat = paramMap.get('lat');
      const lon = paramMap.get('lon');
      if (lat && lon && (lat !== this.currentLat || lon !== this.currentLon)) {
        this.currentLat = lat;
        this.currentLon = lon;
        this.loadWeatherData();
      } else if (!this.weatherData.length) {
        this.loadWeatherData(); // 首次加载默认数据
      }
    });
    this.loading = true;
  }

  // 提取数据加载逻辑为独立方法
  private loadWeatherData(): void {
    this.weatherDataLoading = true;
    this.weatherData = []; // 清空旧数据
    this.lazyWeatherData = []; // 清空懒加载缓存
    this.weatherService
      .getWeatherData(this.currentLat, this.currentLon)
      .pipe(
        finalize(() => (this.weatherDataLoading = false)),
        takeUntil(this.componentDestroyed$)
      )
      .subscribe({
        next: (historicalWeatherData) => {
          const temperatures = historicalWeatherData.hourly.temperature_2m;
          const times = historicalWeatherData.hourly.time.map((time) =>
            this.datePipe.transform(time, 'shortTime')
          );
          const humidities = historicalWeatherData.hourly.relativehumidity_2m;
          const windSpeeds = historicalWeatherData.hourly.windspeed_10m;
          const airPressures = historicalWeatherData.hourly.surface_pressure;
          const windDirections = historicalWeatherData.hourly.winddirection_10m;
          const precipitations = historicalWeatherData.hourly.precipitation;
          const rain = historicalWeatherData.hourly.rain;
          const cloudcover = historicalWeatherData.hourly.cloudcover;
          const soilTemperatures =
            historicalWeatherData.hourly.soil_temperature_0_to_7cm;

          temperatures.forEach((value, i) => {
            this.weatherData.push(
              new WeatherDataItem(
                value,
                times[i],
                humidities[i],
                windSpeeds[i],
                airPressures[i],
                windDirections[i],
                precipitations[i],
                rain[i],
                cloudcover[i],
                soilTemperatures[i]
              )
            );
          });
          // 数据更新后触发懒加载,刷新表格
          if (this.table) {
            this.table.onLazyLoad.emit({
              first: 0,
              rows: 10,
              sortField: this.table.sortField,
              sortOrder: this.table.sortOrder,
              filters: this.table.filters
            });
          }
        },
        error: () =>
          (this.showError = 'Something went wrong. Please try refreshing the page'),
      });
  }

  // ...保留原有loadData、clearFilters、ngOnDestroy方法
}

3. WeatherService优化(可选)

若需要支持动态日期查询,可修改服务方法添加日期参数:

@Injectable({
  providedIn: 'root',
})
export class WeatherService {
  constructor(private http: HttpClient) {}

  getWeatherData(
    lat: string = '51.51',
    lon: string = '-0.13',
    startDate: string = '2005-08-25',
    endDate: string = '2005-08-25'
  ): Observable<WeatherData> {
    return this.http.get<WeatherData>(
      `https://archive-api.open-meteo.com/v1/era5?latitude=${lat}&longitude=${lon}&start_date=${startDate}&end_date=${endDate}&hourly=temperature_2m,relativehumidity_2m,dewpoint_2m,apparent_temperature,surface_pressure,precipitation,rain,cloudcover,windspeed_10m,winddirection_10m,soil_temperature_0_to_7cm`
    );
  }
}

关键说明

  • 通过路由查询参数传递经纬度,适配跨路由组件的数据传递场景
  • 监听queryParamMap变化,支持组件复用(无需销毁重建即可切换城市)
  • 每次切换城市时清空旧数据,避免数据累加,同时触发表格懒加载更新视图
  • 保留原有懒加载、过滤、排序功能,保证用户体验一致性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:50:15