3

我需要根据一些标志来渲染来自不同 ngrx 存储的数据。两家商店都提供相同类型的数据。

方法一

<ng-contaier *ngIf="flag$ | async; else anotherStoreData">
    <ng-container *ngIf="store1$ | async as store1">
        <div>{{ store1?.prop1 }}</div>
        <div>{{ store1?.prop2 }}</div>
    </ng-container>
</ng-contaier>
<ng-template #anotherStoreData>
    <ng-container *ngIf="store2$ | async as store2">
        <div>{{ store2?.prop1 }}</div>
        <div>{{ store2?.prop2 }}</div>
    </ng-container>
</ng-template>

flag$: Observable<boolean>
store1$: Observable<Store>
store2$: Observable<Store>
ngInit() {
    flag$ = streamService.userNewStore();
    store1$ = this.store.select(<someselector1>);
    store2$ = this.store.select(<someselector2>);
}

方法二

<ng-container *ngIf="store$ | async as store">
    <div>{{ store?.prop1 }}</div>
    <div>{{ store?.prop2 }}</div>
</ng-container>


store$: Observable<Store>
ngInit() {
    streamService.userNewStore()
    .pipe(takeUntil(this.ngUnsubscribe))
    .subscribe((flag) => {
        store$ = flag ? this.store.select(<someselector1>) : this.store.select(<someselector2>);
    });
}

在 Approach1 中,我正在复制模板,这对于小模板来说很好 - 但如果它很大,那么我正在考虑 Approach 2。

在 Approach2 中,streamService 可以随时更改标志,在这种情况下,使用异步管道的模板中的先前订阅会发生什么。它会导致任何内存泄漏吗?

有没有其他我可以使用的替代品,请建议。

4

2 回答 2

4

刚刚检查了 Async 管道的源代码,如果 Observable 发生更改,它将取消订阅。

您可以在文件的第 100 行看到这一点:

if (obj !== this._obj) {
  this._dispose();
  return this.transform(obj as any);
}

如果传入的值不是当前保存在内存中的值,它会调用this.dispose,然后取消订阅。

考虑到这一点,我肯定更喜欢第二种方法

于 2018-11-10T23:03:45.187 回答
0

您可以在条件运算符flag$中使用observable来确定数据源:

<ng-container *ngIf="((flag$ | async) ? store1$ : store2$) | async as store">
  <div>{{ store?.prop1 }}</div>
  <div>{{ store?.prop2 }}</div>
</ng-container>  

请参阅此 stackblitz以获取演示。

于 2018-11-10T23:15:14.737 回答