#angular #rxjs #observable
Вопрос:
У меня есть служба, которая предоставляется в корневом каталоге с наблюдаемой:
organizationSubject = new Subject<Organization>();
organization$ = this.organizationSubject.asObservable();
...
constructor(private http: HttpClient) {
this.http
.get<Organization>('organization')
.subscribe((organization) => this.organizationSubject.next(organization));
}
В OrganizationSettings
компоненте я назначаю глобальное наблюдаемое локальному наблюдаемому в ngOnInit
:
this.organization$ = this.organizationService.organization$.pipe(
tap((organization) => {
// side effects here
})
со следующим шаблоном:
<div class="mt-6" *ngIf="organization$ | async as organization" [formGroup]="form">
{{ organization.name }}
</div>
Когда я перехожу на маршрут, где я был OrganizationSettings
в первый раз, страница отображается так, как ожидалось, и я вижу div с Name of my organization
.
Теперь, когда я перехожу на другой маршрут и возвращаюсь, я не вижу названия организации.
Я что-то здесь упускаю? Я ничего не понимаю…
Ответ №1:
Вероятно, вам следует использовать a BehaviorSubject
или a ReplaySubject(1)
вместо базового Subject
, так как он не будет выдавать последние результаты.
Комментарии:
1. Спасибо вам за быстрый и правильный ответ. Я заменил
Subject
наReplaySubject(1)
и теперь получаю ожидаемые результаты.2. Это было связано с так называемой проблемой «позднего подписчика», если вам интересно узнать об этом больше. Альтернативой могло бы быть использование оператора shareReplay ( learnrxjs.io/learn-rxjs/operators/multicasting/sharereplay ), что может свести ваш сервисный код к простому
organization$ = this.http .get<Organization>('organization').pipe(shareReplay(1))
3. Я бы не рекомендовал использовать
shareReplay(1)
с горячими наблюдаемыми. Это сделает наблюдаемое живым «навсегда», даже если вы перейдете на другую страницу и это может привести к утечке памяти. ИспользованиеpublishReplay(1), refCount()
лучше. Пример: blog.strongbrew.io/share-replay-issue