Угловой асинхронный канал и http/delayed observable

Может кто-нибудь объяснить мне, почему в следующем примере @Input имеет значение null, если я обращаюсь к нему в ngOnInit OtherComponent (вызов http был успешным)?

Некоторые компоненты:

@Component({   
selector: 'some-component',   
template: `<other-component [data]="observable$ | async"></other-component>`,   
styles: [``] }) 
export class SomeComponent  {

    observable$: Observable<any>;

    ngOnInit(): void {
      observable$ = this.http.get(...); // service call via angular httpClient 
    }

Другой компонент:

@Component({   
selector: 'other-component',   
template: `<div>...</div>`,   
styles: [``] }) 

export class OtherComponent  {

    @Input()
    data: any;

    ngOnInit(): void {
     // if I access this.data here, it is null
    }

Согласно документации angular, асинхронный канал подписывается на наблюдаемое и возвращает последнее значение, которое он выдал. . Итак, я подумал, что асинхронный канал будет передавать результат http-вызова, а не нуль.

Если я использую *ngIf, результат http-вызова передается вниз, а не нулевой.

<other-component *ngIf="observable$ | async as observable" [data]='observable'>

Пример Stackblitz:

https://stackblitz.com/edit/angular-xghrjg


person mp5er    schedule 21.02.2019    source источник
comment
асинхронный   -  person AJT82    schedule 21.02.2019
comment
stackoverflow .com/questions/748175/   -  person AJT82    schedule 21.02.2019
comment
Я нашел ответ на свой вопрос stackoverflow.com/questions/44044974/   -  person mp5er    schedule 22.02.2019


Ответы (2)


Шаблон:

<other-component [data]='observable$ | async'>

Другой компонент:

@Component({   
selector: 'other-component',   
template: `<div>...</div>`,   
styles: [``] }) 

export class OtherComponent  {

    @Input()
    data: any;

    ngOnInit(): void {}

    ngOnChanges(){
      console.log(this.data);
    }
person Suresh Kumar Ariya    schedule 21.02.2019

Проблема в том, что во время инициализации дочернего компонента (в вашем случае OtherComponent) данных еще не было, потому что данные загружаются асинхронно.

Из-за этого Angular имеет хук жизненного цикла OnChanges, который затем дает вам возможность управлять данными по мере их изменения, поступающего как Input().

Документация -> https://angular.io/guide/lifecycle-hooks#onchanges

Обновленный Stackblitz -> https://stackblitz.com/edit/angular-nkgcj9?file=src%2Fapp%2Fdummy.component.ts

Важная часть

ngOnChanges(changes) {
  this.transformedData = changes.data.currentValue; 
}
person Bruno    schedule 21.02.2019
comment
Я знаю, что это работает с ngOnChanges, но я не хочу заботиться о каких-либо изменениях. Начальное значение наблюдаемого содержит все данные, которые мне нужны. Я просто не понимаю, почему значение null в ngOnInit. Я думал, что асинхронный канал «разрешает» значения наблюдаемых до вызова ngOnInit. - person mp5er; 22.02.2019