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');
}
}
只有当给定的 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 中查找最新发出的值。
我有一个 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');
}
}
只有当给定的 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 中查找最新发出的值。