Angular - как лучше всего обрабатывать тему в сервисе и его подписках? - PullRequest
0 голосов
/ 20 февраля 2019

Я новичок в rxjs, поэтому я, вероятно, не использую его как опытный пользователь.

Я также использую rxjs 5.1.0.

У меня есть служба, где яиметь BehaviorSubject с именем file$ и наблюдаемое из file$ с именем files

@Injectable()
export class UploadService {
  files$: BehaviorSubject<FileToUpload[]> = new BehaviorSubject([]);
  files: Observable<FileToUpload[]> = this.files$.asObservable();

Это немного странно иметь эти переменные-члены.

Это правильно?или как лучше я могу это сделать?

Затем в компонентах onInit я подписываю наблюдателя files:

  ngOnInit() {
    this.fileStateSubscription = this.uploadService.files.subscribe((files) => {

yt Вкл. ngDestroy Я отписался от подписки:

  ngOnDestroy() {
    this.fileStateSubscription.unsubscribe();
  }

Это правильно.Я обеспокоен утечками памяти и т. Д., И я должен каким-то образом быть unsubscribing из files$.

Я не могу отписаться от files$ в ngOndestroy или, по крайней мере, я бы кое-что, как нужно перехватитьснова подписку, но поскольку это переменная-член, это вызовет проблемы.

Должен ли я подписываться и отписываться каждый раз, когда вхожу в этот компонент?

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Вы должны отказаться от подписки на все заметки, на которые вы подписываетесь, если они не заполняются самостоятельно (горячие и холодные заметки, которые вы можете захотеть найти, быстрый поиск в Google даст вам несколько блогов).В вашем случае, если вы ведете темы самостоятельно, вам определенно следует отписаться.

Если у вас есть хорошие переменные-члены, вы можете использовать геттер для наблюдаемых файлов.Я не совсем уверен в соглашении, но я думаю, что переменная files также должна иметь $ в конце.

Способ, которым вы отписываетесь, является правильным, один хороший способ сделать это, особенно если у вас несколько подписок водин компонент должен использовать takeUntil следующим образом:

export class YouComponent implements OnInit, OnDestroy {
private unsubscribe$: Subject<void> = new Subject<void>();

constructor(private yourService: YouService) {}

ngOnInit(): void {
    this.yourService.getFiles().pipe(takeUntil(this.unsubscribe)).subscribe(() => // some code)
    this.yourService.getOtherFiles().pipe(takeUntil(this.unsubscribe)).subscribe(() => // some code)
}

ngOnDestroy(): void {
    this.unsubscribe.next();
    this.unsubscribe.complete();
}
}

Таким образом, вы будете отписываться от всех наблюдаемых, когда this.unsubscribe испускает.

Ах, я только что прочитал, у вас нет каналов: Как япомните, что вы можете просто использовать

yourService.getFiles().takeUntil(this.unsubscribe).subscribe()

вместо

0 голосов
/ 21 февраля 2019

Точка № 1: Мне кажется странным иметь такие переменные-члены:

Лично я предпочитаю следующий синтаксис и также видел его в более крупных проектах:

export class foo {
  private foo$$ = new BehaviorSubject(false);
  public foo$ = this.foo$$.asObservable();
}

$$ для Субъектов и других наблюдаемых взаимодействий, $ для чистых Наблюдаемых, на которые можно подписаться

Точка № 2: Подписаться внутри Сервиса

Ваш сервис не будет иметь ngOnDestroy (, только если вы предоставите его только для одного компонента ), поэтому не только из-за этого, но, пожалуйста, не подписывайтесь на наблюдаемые объекты внутриуслуги .Вы можете сделать это, но, следовательно, вам нужно глубже понять, как сервисы работают и как они работают в модулях.

Точка № 3: Где подписаться и как?

Ну, теперь ваш сервис должен предоставить одну или несколько общедоступных читаемых заметок, которые уже сопоставлены / отфильтрованы / .... и готовы к подписке - .Таким образом, вы можете позволить сервису внедряться в компонент по вашему выбору ( место, где вам нужны данные ).Тогда в компоненте есть два способа управления подписками / отписками.

Я не уверен, что этот вариант доступен для rxjs 5.5, но давайте попробуем:

class foo {

  private subscription = new Subscription();
  constructor(private yourService: YourService) {}
  ngOnInit() {this.subscriptions.add(this.yourService.observable$.subscribe(val => 
  console.log(val)}
  ngOnDestroy() {this.subscriptions.unsibscribe()}
}

Более длинный, но более старый путь

Для каждого Observalbe создайте частный экземпляр Subscription

private observableSubscription;
constructor(...){}
ngOnInit() {this.observableSubscription = yourService.observable$.subscribe(...)}
ngOnDestroy() {this.observableSubscription.unsubscribe()}
...