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

时间:2018-11-28 17:10:54

标签: angular rxjs6

我有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个不必要的订阅?

为防止不必要的操作,我找到了share()。

this.filteredBookings$ = this._filteredBookings
  .asObservable()
  .pipe(
    share()
  );

我认为不需要sharereplay,因为_filteredBookings是一个BehaviorSubject,它始终缓存最后一个值。

文档说:

“只要有至少一个订户,该Observable就会被预订并发出数据。当所有订户都取消订阅时,它将从源Observable取消订阅。”

因此,当我切换路线和负荷组成部分2时,我担心服务中的可观察性被取消吗?因为组件1可以观察到取消订阅(异步管道处理了取消订阅?),所以组件2才可以订阅?

我该如何处理?

1 个答案:

答案 0 :(得分:0)

我已经在这样的服务中做到了:

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