简体   繁体   English

ngOnInit 中未定义 Angular 异步输入?

[英]Angular async input undefined in ngOnInit?

I have a parent component passing in data to a child component from an API like so:我有一个父组件将数据从 API 传递给子组件,如下所示:

.ts .ts

private loadData() {
    this.data = this.apiService.getData();
}

.html .html

<child [data]="data | async"></child>

Then I have a child component that takes this input data and attempts to display/process it like:然后我有一个子组件,它接受这个输入数据并尝试像这样显示/处理它:

export class Child implements OnInit {

  private _data: Data[];

  @Input()
  set data(value: Data[]) {
    this._data = value;
  }

  get data(): Data[] {
    return this._data;
  }

  constructor() {
  }

  ngOnInit() {
    this.processData();
  }

  private processData() {
    const data = this.data; // this is undefined
    // Do processing here
  }
}

I know it is because the data is async and when it calls the ngOnInit the data has not reached that component yet but how can I load the data on init or at least update it when the async completes?我知道这是因为数据是异步的,当它调用 ngOnInit 时,数据尚未到达该组件,但是我如何在 init 上加载数据或至少在异步完成时更新它?

There are multiple options I'm thinking of.我正在考虑多种选择。

The first option is to only create the child component if the API call resolves.第一个选项是仅在 API 调用解决时才创建子组件。

Example:例子:

<ng-content *ngIf="(data | async) as loadedData">
    <child [data]="loadedData"></child>
</ng-content> 

The other option is to listen for @Input changes in your child component with ngOnChanges :另一种选择是使用ngOnChanges监听子组件中的@Input更改:

child.component.ts child.component.ts

@Input() data: Data[];

ngOnChanges(changes: SimpleChanges){
    // If changes.data is set the data input has changed
    if (changes.data) {
        this.processData();
    }
}

The SimpleChanges is a hashtable of changes. SimpleChanges是更改的哈希表。 See ngOnChanges and SimpleChanges for more information;-)有关更多信息,请参阅ngOnChangesSimpleChanges ;-)

The last option would be following in my opinion:我认为最后一个选项如下:

child.component.ts child.component.ts

@Input()
set data(value: Data[]) {
  this._data = value;
  this.processData(); 
}

With the last option you'd process the data every time the setter is called.使用最后一个选项,您将在每次调用 setter 时处理数据。 It is not much different from the second option.它与第二种选择没有太大区别。

I'd suggest you the last option, because you don't need to change a lot;-)我建议你最后一个选项,因为你不需要改变很多;-)

I know this is already answered but I'd like to point out ngOnChanges .我知道这已经得到解答,但我想指出ngOnChanges

SimpleChanges has very cool props like previousValue and currentValue , so you can make things like this: SimpleChanges有非常酷的 props,比如previousValuecurrentValue ,所以你可以做这样的事情:

ngOnChanges(changes: SimpleChanges) {
  const { myExpectedProp } = changes;
  if (myExpectedProp.previousValue !== myExpectedProp.currentValue) {
    this.doSomething();
  }
}

Isn't it awesome?是不是很棒? In case you're not using async pipe, this is very handy.如果您不使用async pipe,这非常方便。

Don't forget to implement the interface:不要忘记实现接口:

import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';

export class YourComponent implements OnInit, OnChanges {
  // ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM