angular присваивает различные наблюдаемые шаблону с помощью async в зависимости от условия (утечка памяти?)

Мне нужно отображать данные из разных хранилищ 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 может изменить флаг в любое время, в этом случае, что произойдет с предыдущей подпиской в ​​шаблоне с асинхронным конвейером. Приведет ли это к утечке памяти?

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


person Dyapa Srikanth    schedule 10.11.2018    source источник


Ответы (2)


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

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

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

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

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

person user184994    schedule 10.11.2018
comment
Вот почему мне нравится stackoverflow? - person Dyapa Srikanth; 11.11.2018

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

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

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

person ConnorsFan    schedule 10.11.2018
comment
@ConnersFan, когда он переключается с store1 $ на store2 $, отменит ли он подписку store1 $ - Если да, есть ли разница в переходе с ngIf и ngOnInit при выборе магазина на основе флага? - person Dyapa Srikanth; 11.11.2018