Угловое назначение различных наблюдаемых для шаблона с асинхронностью в зависимости от условия (утечка памяти?) - PullRequest
0 голосов
/ 11 ноября 2018

Мне нужно визуализировать данные из разных хранилищ ngrx на основе некоторого флага. Оба хранилища дают один и тот же тип данных.

Подход 1

<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>);
}

Подход 2

<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>);
    });
}

В подходе 1 я дублирую шаблон, который подходит для небольших шаблонов, но если он большой, я думаю о подходе 2.

В Approach2 streamService может изменить флаг в любое время, в этом случае, что произойдет с предыдущей подпиской в ​​шаблоне с асинхронным каналом. Приведет ли это к утечке памяти?

Есть ли другие альтернативы, которые я могу использовать, пожалуйста, предложите.

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Вы можете использовать наблюдаемую flag$ в условном операторе для определения источника данных:

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

См. этот стек для демонстрации.

0 голосов
/ 11 ноября 2018

Только что проверив исходный код для асинхронного канала, кажется, что он будет отписываться при изменении наблюдаемого.

Вы можете увидеть это в строке 100 файла :

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

Если передаваемое значение не является текущим в памяти, оно вызывает this.dispose, что, в свою очередь, отменяет подписку.

Имея это в виду, я бы определенно предпочел второй подход

...