Angular 5 ждет нескольких дочерних уведомлений - PullRequest
0 голосов
/ 31 октября 2018

У меня есть родительский компонент, который включает в себя два дочерних компонента. Каждый из дочерних элементов имеет собственную сетевую нагрузку, и мне нужно знать в родительском компоненте, когда оба дочерних элемента закончили с сетевыми нагрузками. Я предполагал, что могу использовать наблюдаемое для этого, но у меня это не сработало. В обоих моих дочерних компонентах я сделал это:

private _loadFinished = new BehaviorSubject<boolean>(null);
loadFinished = this._loadFinished.asObservable();

networkLoad() {
   this.network.doLoad().subscribe(x => {
       this._loadFinished.next(true);
   });
}

В родительском HTML я пометил каждый дочерний компонент, а затем в коде я сделал это:

@ViewChild('orgMetrics') orgMetrics: ChildComponentOne;
@ViewChild('campusMetrics') campusMetrics: ChildComponentTwo;

loading = true;

ngOnInit(): void {
    forkJoin(
        this.orgMetrics.loadFinished,
        this.campusMetrics.loadFinished
    ).subscribe(() => {
        console.info("I got here");
        this.loading = false;
    }, () => this.loading = false);
}

}

subscribe никогда не получает удар, хотя. Я иду в совершенно неправильном направлении? Я также смотрел на en EventEmitter, но я не понимал, как я буду ждать выполнения обоих действий, прежде чем действовать.

Ответы [ 3 ]

0 голосов
/ 31 октября 2018

Вы можете сделать это с помощью EventEmitter

Родитель:

import { Component } from '@angular/core';
@Component({
  selector: 'app-parent',
  templateUrl: './parent.html'
})
export class ParentComponent {
  onChanges(event){
    console.log(event);
  }
}

Родительский HTML:

<app-child (valueChange)="onChanges($event)"></app-child>

Ребенок:

import { Component, EventEmitter } from '@angular/core';
@Component({
  selector: 'app-child',
  templateUrl: './child.html'
})
export class ChildComponent {
  @Output() valueChange = new EventEmitter();

  networkFinished() {
    this.valueChange.emit('child1');
  }
}

Вот рабочий пример

0 голосов
/ 31 октября 2018

Функция forkJoin будет генерироваться только тогда, когда для данных наблюдаемых завершено завершено . то есть, он не будет излучать, когда вы задаете Наблюдаемые, просто испускают своих собственных значений.

Поскольку вы используете BehaviorSubject , при вызове this._loadFinished.next(true) будет выдано только одно значение из наблюдаемого, и оно не будет завершено.

Быстрое решение - просто позвонить _loadFinished.complete() после выдачи единственного значения:

networkLoad() {
   this.network.doLoad().subscribe(x => {
       this._loadFinished.next(true);
       this._loadFinished.complete();
   });
}

Если у вас была какая-то причина держать BehaviorSubjects вокруг, вы также можете найти более подходящим оператор Observable.combineLatest , так как он просто ищет последние значения, полученные в Observable.

0 голосов
/ 31 октября 2018

Вы обращаетесь к компоненту @ViewChild ('orgMetrics') 'внутри ngOnInit (). Но правильный путь - использование ngAfterViewInit (). Другой способ - объявить BehaviorSubject Observable и Observer внутри службы и получить доступ через компонент.

Услуги:

private _loadFinished = new BehaviorSubject<boolean>(null);
loadFinished = this._loadFinished.asObservable();
private _loadFinished1 = new BehaviorSubject<boolean>(null);
loadFinished1 = this._loadFinished1.asObservable();

load1Finished(){ //call this method from child component
  this.loadFinished.next(true);
}

load2Finished(){ //call this method from child component
  this.loadFinished1.next(true);
}

Родительский компонент:

loading = true;

ngOnInit(): void {
    forkJoin(
        this.Service.loadFinished,
        this.Service.loadFinished1
    ).subscribe(() => {
        console.info("I got here");
        this.loading = false;
    }, () => this.loading = false);
}
...