Оператор Rxjs share () с темой поведения и асинхронным каналом - угловой - PullRequest
0 голосов
/ 10 октября 2018

У меня есть BehaviorSubject, который используется как наблюдаемая:

testForStack$: Observable<boolean>;

ngOnInit(){
    const bs = new BehaviorSubject(true);
    this.testForStack$ = bs
      .asObservable()
      .do(t => console.log('subscribed'))
      .share();
}

Эта наблюдаемая проходит через три асинхронных канала в шаблоне:

Sub1: {{testForStack$ | async}}<br>
Sub2: {{testForStack$ | async}}<br>
Sub3: {{testForStack$ | async}}

Проблема только впервое (Sub1) получает значение true

Sub1: true
Sub2: 
Sub3:

Если я удаляю .share (), все три значения получают значение true, но это вызывает проблему нескольких подписок.

Любые мысли о том, почему использование BehaviorSubject вызывает такое поведение?Он используется в качестве наблюдаемой, поэтому я предполагаю, что приведенный выше код будет работать правильно.

Это также похоже на этот ответ:

https://stackoverflow.com/a/40819423/4912604

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Не используйте оператор обмена.Вместо этого сделайте что-то вроде этого:

<ng-container *ngIf="testForStack$ | async as testForStack">

  Sub1: {{ testForStack }}
  Sub2: {{ testForStack }} 
  Sub3: {{ testForStack }}

</ng-container>

Существуют различные другие способы, например, вы можете использовать тот же подход с шаблоном, используя ngTemplateOutlet, если вам не нравится использование * ngIf.Этот подход позволяет вам создать переменную псевдонима таким же образом:

<ng-template let-testForStack [ngTemplateOutletContext]="{ $implicit: testForStack$ | async }" [ngTemplateOutlet]="selfie" #selfie>

  Sub1: {{ testForStack }}
  Sub2: {{ testForStack }} 
  Sub3: {{ testForStack }}

</ng-template>

Этот ng-template код является самоссылкой (которая действительна) и полностью не проверен, но "должен" работать и избегает использования *ngIf

Подробнее здесь: https://nitayneeman.com/posts/using-single-subscription-for-multiple-async-pipes-in-angular/

0 голосов
/ 10 октября 2018

Это правильное поведение.Оператор share() сохраняет только одну подписку для своего родителя, а BehaviorSubject выдает свое значение только при подписке.

Это означает, что при использовании первого {{testForStack$ | async}} он подписывается в конце цепочки на share(), который подписывается на своих родителей, что приводит к подписке на источник BehaviorSubject, который немедленно выдает свое значение.

Однако второй и все последовательные {{testForStack$ | async}} подписываются на share(), который уже подписался на егоparent и больше не будет подписываться, поэтому нечего передавать исходное значение этим наблюдателям.

Простым решением может быть использование shareReplay(1) (в зависимости от вашей версии RxJS), вам, вероятно, следует использовать publishReplay(1).refCount()вместо этого из-за этих проблем (или его переносимых эквивалентов):

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...