У меня есть служба Angular, которая хранит приватный BehaviorSubject, чтобы он мог считывать значение в любой момент времени. Он является закрытым, поэтому любой компонент, который его использует, не может им манипулировать. Вместо этого обычный Observable отображается как общедоступный. BehaviorSubject теперь является потребителем любых данных, испускаемых этим наблюдаемым.
public subheaderData$: Observable<SubheaderData>;
private subheaderDataSubject$: BehaviorSubject<SubheaderData> = new BehaviorSubject<SubheaderData>(null);
constructor(private repository: SubHeaderRepository) {
this.subheaderData$ = this.load();
this.subheaderData$.subscribe(this.subheaderDataSubject$);
}
Как видите, я звоню .subscribe из своего сервиса, что сразу делает мой наблюдаемый горячим. Что я хотел бы сделать, так это то, что компонент, который внедряет эту службу, должен подписаться на общедоступную Observable, и когда это произойдет, BehaviorSubject должен автоматически добавляться в качестве наблюдателя, даже если компонент не знает об этом (из-за того, что он частный.
Как это можно сделать?
@martin - Когда компонент подписывается на subheaderData$, который находится в службе, я хочу, чтобы служба прикрепляла subheaderDataSubject$ в качестве наблюдателя.
Поэтому, когда кто-то подписывается на subheaderData$, он должен автоматически подписываться this.subheaderDataSubject$ на subheaderData$.
@martin да, это правильно.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Сделайте это в своем сервисном конструкторе
this.subheaderData$ = this.subheaderDataSubject$.asObservable();
затем подпишитесь на subheaderData$, когда это необходимо
а можно this.subheaderDataSubject$.next(someValue) к вашим услугам
Если я не упустил ничего важного, я думаю, вы сможете добиться того, чего хотите, только с помощью multicast, хотя это будет немного необычный вариант использования.
subheaderDataPublic$ = this.subheaderData$.pipe(
multicast(this.subheaderDataSubject$, s => s),
);
Затем в своем компоненте вы подпишетесь на subheaderDataPublic$.
Как правило, вы бы использовали multicast, например, так:
multicast(new Subject(), s => merge(s, s.pipe(...)))
... но если вы пройдете его this.subheaderDataSubject$, он будет использоваться как промежуточный предмет. Это s => s выше требуется, потому что без какой-либо функции выбора multicast возвращает экземпляр ConnectableObservable, который, вероятно, вам не нужен.
Обновлено: Возможно, более понятным решением было бы использование только конструктора Observable.
subheaderDataPublic$ = new Observable(observer => {
const subscriptions = new Subscription();
subscriptions.add(this.subheaderData$.subscribe(this.subheaderDataSubject$));
subscriptions.add(this.subheaderDataSubject$.subscribe(observer));
return () => subscriptions.unsubscribe();
});
Итак, вы хотите, чтобы
subheaderDataSubject$подписывался наsubheaderData$только тогда, когда наsubheaderDataSubject$есть хотя бы один подписчик?