RxJS Observable — прикрепить субъект к подписке

У меня есть служба 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 должен автоматически добавляться в качестве наблюдателя, даже если компонент не знает об этом (из-за того, что он частный.

Как это можно сделать?

Итак, вы хотите, чтобы subheaderDataSubject$ подписывался на subheaderData$ только тогда, когда на subheaderDataSubject$ есть хотя бы один подписчик?

martin 07.03.2019 18:16

@martin - Когда компонент подписывается на subheaderData$, который находится в службе, я хочу, чтобы служба прикрепляла subheaderDataSubject$ в качестве наблюдателя.

blgrnboy 07.03.2019 18:20

Поэтому, когда кто-то подписывается на subheaderData$, он должен автоматически подписываться this.subheaderDataSubject$ на subheaderData$.

martin 07.03.2019 18:22

@martin да, это правильно.

blgrnboy 07.03.2019 18:23
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
143
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Сделайте это в своем сервисном конструкторе

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

Другие вопросы по теме