如何在Angular 6中仅将一个值从一个组件传递到另一组件?

时间:2018-10-02 18:47:21

标签: angular typescript angular6

如何在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;
   }
}

有什么建议吗?

2 个答案:

答案 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
      });

  }

}