Angular天气应用技术问题:表单城市值无法传递至Service并更新API请求参数
嘿,我帮你梳理下问题出在哪,然后一步步解决它~
问题根源分析
你当前的代码存在几个关键问题:
WeatherService里的name是硬编码的全局变量,没有提供动态修改它的方式,而且getWeatherData方法也不接收外部传入的城市参数;WeatherFormComponent的submit方法里,既没把表单输入的城市名传给 Service,还错误地 emit 了未赋值的this.weather;WeatherCardComponent没有监听子组件的事件,表单提交后也不会重新请求新城市的天气数据。
分步解决方案
1. 改造 WeatherService,支持动态传入城市参数
首先去掉硬编码的 name,让 getWeatherData 方法接收城市参数,这样每次调用都能请求不同城市的数据:
import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { HttpClient } from '@angular/common/http'; const serviceUrl = 'http://api.weatherapi.com/v1/current.json'; const apiKey = 'someAPIKey'; // 记得替换成你的真实API密钥 @Injectable({ providedIn: 'root', }) export class WeatherService { constructor(private http: HttpClient) {} // 新增city参数,动态生成请求URL getWeatherData(city: string): Observable<any> { return this.http.get( `${serviceUrl}?key=${apiKey}&q=${city}&aqi=no` ); } }
2. 修复 WeatherFormComponent,正确传递城市名
修改表单组件的逻辑,提交时把输入的城市名 emit 给父组件,而不是自己去调用 Service:
import { Component, OnInit, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-weather-form', templateUrl: './weather-form.component.html', styleUrls: ['./weather-form.component.scss'], }) export class WeatherFormComponent implements OnInit { @Output() citySubmitted = new EventEmitter<string>(); name = ''; // 初始化空字符串,避免类型问题 ngOnInit(): void {} submit() { if (this.name.trim()) { // 先校验输入不为空 this.citySubmitted.emit(this.name); // 把城市名传给父组件 this.name = ''; // 提交后清空输入框 } } }
3. 改造 WeatherCardComponent,监听表单事件并刷新数据
首先在模板里绑定子组件的 citySubmitted 事件:
<div class="input-container"> <!-- 绑定子组件的事件,触发父组件的方法 --> <app-weather-form (citySubmitted)="onCitySubmitted($event)"></app-weather-form> </div> <div *ngFor="let item of weathers[0]; first as isFirst"> <div *ngIf="!isFirst"> <mat-card class="mat-card"> <p><strong>Name :</strong>{{ item.name }}</p> <p><strong>State :</strong> {{ item.region }}</p> <p><strong>Country :</strong>{{ item.country }}</p> <p><strong>Latitude:</strong> {{ item.lat }}</p> <p><strong>Longitude:</strong> {{ item.lon }}</p> </mat-card> </div> </div>
然后修改组件类,添加事件处理方法,并支持动态请求城市数据:
import { Component, OnInit } from '@angular/core'; import { WeatherService } from '../../services/weather.service'; @Component({ selector: 'app-weather-card', templateUrl: './weather-card.component.html', styleUrls: ['./weather-card.component.scss'], }) export class WeatherCardComponent implements OnInit { weathers: any = []; constructor(public weatherService: WeatherService) {} ngOnInit() { // 初始化时请求默认城市,比如mumbai this.getWeatherData('mumbai'); } // 修改方法为接收城市参数 getWeatherData(city: string) { this.weatherService.getWeatherData(city).subscribe((data) => { this.weathers = Object.entries(data); console.log(this.weathers); }); } // 处理子组件传来的城市名,重新请求数据 onCitySubmitted(city: string) { this.getWeatherData(city); } }
最后别忘了检查依赖
确保你的 AppModule 里导入了 FormsModule(因为用到了 [(ngModel)] 双向绑定):
// app.module.ts import { FormsModule } from '@angular/forms'; @NgModule({ imports: [ // ...其他模块 FormsModule ], // ... }) export class AppModule { }
这样修改后,当你在表单输入城市名提交时,父组件会收到这个城市名,调用 Service 请求对应数据,页面就会自动更新新城市的天气信息啦~
内容的提问来源于stack exchange,提问作者Shaswati Bhattacharyya
相关产品推荐
相关产品推荐

