提问者:小点点

共享可观察数据的正确方式和地点是什么


我有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可以订阅之前取消订阅(异步管道处理取消订阅?)?

我该怎么处理?


共1个答案

匿名用户

我在服务中这样做过:

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

相关问题