【问题标题】:How to pass only one value from one component to other component in Angular 6?如何在Angular 6中只将一个值从一个组件传递给另一个组件?
【发布时间】:2019-03-07 22:45:00
【问题描述】:

如何在 Angular 6 中将数据从一个组件传递到另一个组件?我创建了服务(weather.service)、weather.component、interface和app.component。因此,我在 weather.component 中有来自天气 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);

}

}

app.component

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;
}

weather.service

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({ 提供在:“根” }) 导出类 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;
   }
}

请问有什么建议吗?

【问题讨论】:

标签: angular typescript angular6


【解决方案1】:

你需要一个@Output 发送到父组件。这是您将如何传递它的方法。你也应该从constructor中取出weatherId检查并将其放入ngOnInit

current-weather.component.ts

@Output() weatherId: EventEmitter<boolean> = new EventEmitter();

ngOnInit() {
this.weatherService.getCurrentWeather('Seattle', 'US')
  .subscribe((data) => {
      this.current = data;
      this.weatherId.emit(data.weatherId);
    });

}

app.component.html

<app-current-weather (weatherId)="updateWeatherId($event)"></app-current-weather>

app.component.ts

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';
    }
  }
}

【讨论】:

  • 它不起作用,因为编译器显示错误 - updateWeatherId 未定义
  • 您确实将updateWeatherId() 函数放在了 app.component.ts 中,对吗?否则我不知道该告诉你什么,因为我们在那里确实定义了它。
  • 是的,我把 updateWeatherID 放在了 ngOninit 中。它看起来像 - ngOnInit() { updateWeatherId(weatherId){ if (weatherId > 800) { ....}
  • 我更新了我的答案,以便更直接地说明将天气 ID 检查添加到 ngOnInit 的意思。
  • 感谢您的帮助。它正在工作。我只是在这里稍作改动 -> ngOnInit() { this.updateWeatherId(this.weatherID); }
【解决方案2】:

由于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
      });

  }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多