如何在Angular 6中将数据从一个组件传递到另一个组件?我创建了服务(weather.service),weather.component,接口和app.component。因此,我在weather.component中有来自weather api的数据,但我想将数据传递到app.component并使用它动态更改背景图像。 current-weather.component
import {Component, OnInit} from '@angular/core';
import {ICurrentWeather} from '../icurrent-weather';
import {WeatherService} from '../weather/weather.service';
@Component({
selector: 'app-current-weather',
templateUrl: './current-weather.component.html',
styleUrls: ['./current-weather.component.css']
})
export class CurrentWeatherComponent implements OnInit {
current: ICurrentWeather;
constructor(public weatherService: WeatherService) {
this.current = {
city: '',
country: '',
image: '',
temperature: 80,
description: '',
natural: '',
bgImage: '',
visibility: 12478,
weatherId: 200,
} as ICurrentWeather;
}
ngOnInit() {
this.weatherService.getCurrentWeather('Seattle', 'US')
.subscribe((data) => this.current = data);
}
}
应用组件
import {Component} from '@angular/core';
import {ICurrentWeather} from './icurrent-weather';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
weatherID: ICurrentWeather;
bgImage: string;
constructor() {
if ( this.weatherID.weatherId > 800) {
this.bgImage = '../../../assets/images/cloud.jpg';
} else if (this.weatherID.weatherId === 800) {
this.bgImage = '../../../assets/images/clear.jpg';
} else if (this.weatherID.weatherId >= 700) {
this.bgImage = '../../../assets/images/fog.png';
} else if (this.weatherID.weatherId >= 600) {
this.bgImage = '../../../assets/images/snow.png';
} else if (this.weatherID.weatherId >= 500) {
this.bgImage = '../../../assets/images/rain.png';
} else if (this.weatherID.weatherId >= 300) {
this.bgImage = '../../../assets/images/drizzly.png';
} else {
this.bgImage = '../../../assets/images/thunderstorm.jpg';
}
}
}
界面
export interface ICurrentWeather {
city: string;
country: string;
image: string;
temperature: number;
description: string;
natural: string;
weatherId: number;
visibility: number;
}
天气服务
import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {environment} from '../../environments/environment';
import {Observable} from 'rxjs';
import {ICurrentWeather} from '../icurrent-weather';
import {map} from 'rxjs/internal/operators';
interface ICurrentWeatherData {
weather: [{
main: string, // main:'Rain'
description: string,
icon: string,
id: number,
}];
main: {
temp: number
};
visibility: number; // visibility: 12874
sys: {
country: string
};
name: string;
}
@Injectable({ providerIn:'root' }) 导出类WeatherService {
constructor(private http: HttpClient) { }
getCurrentWeather(city: string, country: string):
Observable<ICurrentWeather> {
return this.http.get<ICurrentWeatherData>(
`http://api.openweathermap.org/data/2.5/weather?
q=${city},${country}&APPID=${environment.apiID}`
).pipe(
map(data => this.transformToICurrentWeather(data))
);
}
private transformToICurrentWeather(data: ICurrentWeatherData):
ICurrentWeather {
return {
city: data.name,
country: data.sys.country,
image: `http://openweathermap.org/img/w/${data.weather[0].icon}.png`,
temperature: this.convertKelvinToFahrenheit(data.main.temp),
description: data.weather[0].description,
natural: data.weather[0].main,
weatherId: data.weather[0].id,
visibility: data.visibility,
};
}
private convertKelvinToFahrenheit(kelvin: number): number {
return kelvin * 9 / 5 - 459.67;
}
}
有什么建议吗?
答案 0 :(得分:1)
您需要一个constructor
才能发送到父组件。这是您将如何传递的方法。您也应该从ngOnInit
中取出weatherId检查并将其放入@Output() weatherId: EventEmitter<boolean> = new EventEmitter();
ngOnInit() {
this.weatherService.getCurrentWeather('Seattle', 'US')
.subscribe((data) => {
this.current = data;
this.weatherId.emit(data.weatherId);
});
}
current-weather.component.ts
<app-current-weather (weatherId)="updateWeatherId($event)"></app-current-weather>
app.component.html
ngOnInit() {
this.updateWeatherId(this.weatherID.weatherId);
}
updateWeatherId(weatherId) {
if ( weatherId > 800) {
this.bgImage = '../../../assets/images/cloud.jpg';
} else if (weatherId === 800) {
this.bgImage = '../../../assets/images/clear.jpg';
} else if (weatherId >= 700) {
this.bgImage = '../../../assets/images/fog.png';
} else if (weatherId >= 600) {
this.bgImage = '../../../assets/images/snow.png';
} else if (weatherId >= 500) {
this.bgImage = '../../../assets/images/rain.png';
} else if (weatherId >= 300) {
this.bgImage = '../../../assets/images/drizzly.png';
} else {
this.bgImage = '../../../assets/images/thunderstorm.jpg';
}
}
}
app.component.ts
v-bind
答案 1 :(得分:1)
由于CurrentWeatherComponent
将是AppComponent
的直接子代(我认为),因此该子代可以将父代注入构造函数中,并从那里构造父代,以便在需要更改图像时到达父代。像这样:
import {Component, OnInit} from '@angular/core';
import {ICurrentWeather} from '../icurrent-weather';
import {WeatherService} from '../weather/weather.service';
import {AppComponent} from '../../app.component'; // change path if incorrect
@Component({
selector: 'app-current-weather',
templateUrl: './current-weather.component.html',
styleUrls: ['./current-weather.component.css']
})
export class CurrentWeatherComponent implements OnInit {
current: ICurrentWeather;
// inject weather service and parent component
constructor(public weatherService: WeatherService, private parent: AppComponent) { }
ngOnInit() {
this.current = {
city: '',
country: '',
image: '',
temperature: 80,
description: '',
natural: '',
bgImage: '',
visibility: 12478,
weatherId: 200,
} as ICurrentWeather;
this.weatherService.getCurrentWeather('Seattle', 'US')
.subscribe((data) => {
this.current = data;
this.parent.changeImage(data); // call some function in parent to swap image
});
}
}