【问题标题】:Passing data from service to parent then from parent to child component将数据从服务传递到父组件,然后从父组件传递到子组件
【发布时间】:2019-02-14 06:30:58
【问题描述】:

好的,伙计们,我是 Angular 的新手,我遇到了一个问题,我不知道我做错了什么。

我的父组件看起来像这样,我正在尝试将 weekly 变量传递给我的子组件:

app.component.ts

import { Component } from "@angular/core";
import { GeolocationService } from "./geolocation.service";
import { WeatherService } from "./weather.service";
import { kmphToMs } from '../utilities/helpful';

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  latitude: number;
  longitude: number;
  cityName: string;
  currentTemp: number;
  currentHumidity: number;
  currentWindSpeed: string;
  weekly: Array<object>;
  erroMessage: string;

  constructor(
    private geolocationService: GeolocationService,
    private weatherService: WeatherService
  ) {}

  ngOnInit() {
    this.geolocationService.getCoordinates().subscribe(result => {
      console.log(result);
      this.latitude = result.coords.latitude;
      this.longitude = result.coords.longitude;
      this.weatherService
        .getTheWeather(this.latitude, this.longitude)
        .subscribe(weatherData => {
          console.log(weatherData);
          this.cityName = weatherData["timezone"];
          this.currentTemp = weatherData["currently"]["temperature"];
          this.currentWindSpeed = kmphToMs(weatherData["currently"]["windSpeed"]);
          this.currentHumidity = weatherData['currently']['humidity'] * 100;
          this.weekly = weatherData['daily']['data'];
          console.table(this.weekly);
        });
    });
  }
}

app.component.html

  <app-days
    [weekly]="weekly"
  ></app-days>

这就是我的子组件的样子:

import { Component, OnInit, Input } from "@angular/core";

@Component({
  selector: "app-days",
  templateUrl: "./days.component.html",
  styleUrls: ["./days.component.css"]
})
export class DaysComponent implements OnInit {
  @Input() weekly: Array<object>;


  constructor() {
  }

  ngOnInit() {
    console.log(this.weekly); 
  }
}

我正在尝试 console.log 每周变量,但它说它未定义,我不知道为什么

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    您的AppComponent 的模板将在您的订阅完成之前开始加载。在此之前,weekly 变量将在 AppComponent 上未定义。

    尝试在ngOnChanges 中阅读。这就是每次在组件上更改 @Input 属性时调用的内容。因此,一旦 weekly 在 AppComponent 中初始化,ngOnChanges 就会使用更新后的 weekly 值被调用。

    import { Component, OnChanges, Input } from "@angular/core";
    
    @Component({
      selector: "app-days",
      templateUrl: "./days.component.html",
      styleUrls: ["./days.component.css"]
    })
    export class DaysComponent implements OnChanges {
      @Input() weekly: Array<object>;
    
      constructor() {
      }
    
      ngOnChanges() {
        console.log(this.weekly); 
      }
    
    }
    

    为了防止undefined 值,您可以在AppComponent 的模板中放置一个*ngIf

    <app-days *ngIf="weekly" [weekly]="weekly" ></app-days>
    

    【讨论】:

      【解决方案2】:

      您的 GEO 服务正在异步设置每周变量。因此,当子组件的 ngOnInit 方法被调用时,父组件中的异步调用可能还没有完成。

      在您的子模板 html 中添加 {{weekly|json}} 以调试数据是否已设置。

      【讨论】:

        【解决方案3】:

        每周的原因最初在 AppComponent 中未定义,并且从结果 geolocationService.getCoordinates() 异步填充。

        但是,在 DaysComponent 中,您尝试在 ngOnInit 挂钩上引用每周数据,这并不能保证此服务调用会完成。

        以下是您可以执行的一些建议:

        1. 根据是否存在每周向 app-days 添加 ngIf 指令。或者,

        2. 在 DaysComponent 中实现 OnChanges 并在以下情况下继续您的工作 每周输入已更改。或

        3. 您可以通过 Subject/Observable 宣布更改并监听组件中的更改并做出相应反应。

        【讨论】:

        • 哪一个是最佳实践?
        • 在使用*ngIf 定义每周之前阻止子组件的呈现。其他两个选项并不是真正需要的,并且会增加您的应用程序的复杂性而不会增加任何价值。
        猜你喜欢
        • 2019-01-21
        • 2019-02-27
        • 2017-04-20
        • 2020-10-22
        • 2017-06-10
        • 2018-02-15
        • 2016-10-13
        相关资源
        最近更新 更多