У меня есть простое приложение, целью которого является получение текущей погоды для местоположения.Это местоположение имеет значение по умолчанию, но у одного из компонентов есть кнопки, которые должны изменить местоположение, вызвать API, а затем повторно отобразить данные.
Итак, у меня есть два компонента: Location и WeatherDisplay.У меня также есть Служба, которая выполняет тяжелую работу (в основном вызывая API).
Моя проблема в том, что WeatherDisplay не меняется, когда пользователь нажимает на новое местоположение.Я новичок в Angular, поэтому дайте мне знать, если я пропущу что-то в этой «презентации».
Я пробовал несколько разных вещей, и я думаю, что я сузил это до чего-то в APIОбслуживание.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { MessageService } from './message.service';
import { BehaviorSubject } from 'rxjs';
import { WeatherStruct } from './weather';
const API_URL = 'http://api.openweathermap.org/data/2.5/weather';
// my key for the OpenWeatherAPI
const API_KEY = '3f25...'; // deleted most of what my key is just 'cause
// default location
const LOCATION_ID = '4480285'; // Morrisville, NC
// get the value from the message
@Injectable({
providedIn: 'root'
})
export class APIService {
private locationSource: BehaviorSubject<any> = new BehaviorSubject(null);
currentLocation = this.locationSource.asObservable();
constructor(
private httpClient: HttpClient,
private msgService: MessageService
) {}
getWeather(loc_id = '4480285'){
// this.msgService.add('api.service.ts '+loc_id);
console.log('api.service getWeather('+loc_id+')');
const api_string = `${API_URL}?id=${loc_id}&APPID=${API_KEY}&units=imperial`;
console.log(api_string);
return this.httpClient.get(api_string);
}
changeLocation(locid: string) {
console.log('api.service changeLocation('+locid+')');
this.locationSource.next(locid);
// need to tell weather-display to re-fetch the data
this.getWeather(locid);
}
}
в шаблоне компонента местоположения у меня есть:
<button (click)="newLocation('5391811')">San Diego, CA</button>
компонент отображения погоды:
import { Component, OnInit } from '@angular/core';
import { MessageService } from '../message.service';
import { WeatherStruct } from '../weather';
import { APIService } from '../api.service';
@Component({
selector: 'app-weather-display',
templateUrl: './weather-display.component.html',
providers: [APIService],
styleUrls: ['./weather-display.component.css']
})
export class WeatherDisplayComponent implements OnInit {
weather: WeatherStruct;
private today: number = Date.now();
loc_id: string;
constructor(
private apiService: APIService,
private msgService: MessageService
) {}
ngOnInit() {
this.apiService.currentLocation
.subscribe(location => this.loc_id = location);
this.fetchWeather();
console.log('CCC');
}
fetchWeather(loc_id = '4480285') {
console.log('weather-display.component showWeather(' + loc_id + ')');
this.apiService.getWeather(loc_id).subscribe((data: WeatherStruct) => {
this.weather = data;
this.weather['today'] = this.today;
});
}
}
и в location.component.ts:
export class LocationComponent implements OnInit {
location: string;
@Output() talk: EventEmitter<string> = new EventEmitter<string>();
constructor(private apiService: APIService,
private msgService: MessageService) {}
ngOnInit() {
this.apiService.currentLocation.subscribe(
location => (this.location = location)
);
}
newLocation(newLoc: string) {
console.log('location.component newLocation('+newLoc+')');
// use an event emiitter
this.talk.emit(newLoc);
// call a function in the service
this.apiService.changeLocation(newLoc);
}
}
и, наконец, в app.component.ts
export class AppComponent implements OnInit {
location: string;
constructor(private apiService: APIService) {}
title = 'The Weather';
ngOnInit() {
this.apiService.currentLocation.subscribe(
location => (this.location = location)
);
}
goGetWeather(newLoc){
console.log("app.component.goGetWeather("+newLoc+")");
}
}
Когда я запускаю свое приложение и пытаюсь нажать на кнопку, я вижу, что код выполняется так, как я ожидаю:
location.component newLocation () вызывается, что вызывает app.component.goGetWeather [который сообщает мне, что работает источник событий];и api.service changeLocation , что приводит к api.service getWeather , который создает правильно отформатированную строку API для вызова
http://api.openweathermap.org/data/2.5/weather?id=2643743&APPID=3f25...&units=imperial
, но ничего не изменяется в компоненте DisplayWeather.
Я знаю, что это что-то простое, но я просто не могу понять, в чем дело.