我有2个组件和一个提供可观察的服务。两个组件都懒加载了那里的模块。
服务:
this.filteredBookings$ = this._filteredBookings
.asObservable()
.pipe(
tap(s => {
console.log(s, 'activity');
return s;
})
);
我在这里添加了点击以查看任何订阅活动。
组件1:
this.bookings$ = this._bookingService.filteredBookings$;
this.sum$ = this.bookings$.pipe(
map(bookings => bookings
.map(booking => booking.value)
.reduce((total, value) => total + value, 0)
)
);
组件1模板:
<ion-list *ngIf="bookings$ | async; let bookings; else loading">
...
<ion-label slot="end" text-right>
<ion-text color="medium"><b>{{ sum$ | async }}</b></ion-text>
</ion-label>
</ion-list>
...
组件2:
this.bookings$ = this._bookingService.filteredBookings$;
我想防止不必要的订阅。当我正确理解时,组件1中的两个可观察对象订阅了服务提供的可观察对象。组件1模板中的异步管道也订阅了这个可观察对象。所以有4个订阅/3个不必要的订阅?
为了防止我发现的不必要的分享()。
this.filteredBookings$ = this._filteredBookings
.asObservable()
.pipe(
share()
);
我认为不需要share replay,因为_filteredBookings是一个行为主题,它总是缓存最后一个值。
文档说:
"只要至少有一个订阅者,这个可观察对象就会被订阅并发出数据。当所有订阅者都取消订阅时,它将取消订阅源可观察对象。"
所以当我切换路由并加载组件2时,我担心服务中的可观察对象被取消?因为组件1可观察对象在组件2可以订阅之前取消订阅(异步管道处理取消订阅?)?
我该怎么处理?
我在服务中这样做过:
private productsUrl = 'api/products';
private products: IProduct[];
private selectedProductSource = new BehaviorSubject<IProduct | null>(null);
selectedProductChanges$ = this.selectedProductSource.asObservable();
constructor(private http: HttpClient) { }
changeSelectedProduct(selectedProduct: IProduct | null): void {
this.selectedProductSource.next(selectedProduct);
}
getProducts(): Observable<IProduct[]> {
if (this.products) {
return of(this.products);
}
return this.http.get<IProduct[]>(this.productsUrl)
.pipe(
tap(data => console.log(JSON.stringify(data))),
tap(data => this.products = data),
catchError(this.handleError)
);
}
下面是我的例子:https://github.com/DeborahK/Angular-Communication/tree/master/APM-Final
我不明白“防止不必要的订阅”的问题?
如果你想要一个更正式的模式,你可以看看NgRx。我这里有一个例子:https://github.com/DeborahK/Angular-NgRx-GettingStarted