Angular 5 等待多个 child 通知

Angular 5 wait for multiple child notifications

我有一个 parent 组件,其中包含两个 child 组件。 children 中的每一个都有自己的网络负载,我需要在 parent 组件中知道两个 children 何时都完成了他们的网络负载。我以为我可以为此使用可观察对象,但它对我不起作用。在我的两个 child 组件中,我都这样做了:

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

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

在 parent 的 HTML 中,我标记了每个 child 组件,然后在代码中我这样做了:

@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 但我不明白在采取行动之前我将如何等待两者都完成。

您正在访问 ngOnInit() 中的“@ViewChild('orgMetrics')”组件。但正确的方法是使用 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);
}

您可以使用 EventEmitter

Parent:

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

Parent Html:

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

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

Here is a working example

只有当给定的 Observables 完成 时,forkJoin 函数才会发出。也就是说,当你给它的 Observables 只是 emit 它们自己的值时,它不会发出。

因为您正在使用 BehaviorSubject,调用 this._loadFinished.next(true) 只会从 Observable 发出一个值,并且不会完成。

一个快速的解决方法是在发出唯一的值后简单地调用 _loadFinished.complete()

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

如果您出于某种原因保留 BehaviorSubjects,您可能还会发现 Observable.combineLatest 运算符更合适,因为它只是从 Observable 中查找最新发出的值。