Наблюдаем, отписаться в ngOnDestroy не получается

У меня есть диалоговое окно, которое открывается и содержит компонент ... в компоненте я оформляю подписку. При закрытии хочу отписаться ..

private deviceObserver: Observable<BreakpointState> = this.breakpointObserver.observe([Breakpoints.XSmall]);

this.deviceObserver.subscribe(result => {
  if (result.matches) {
    this.deviceType = 'mobile';
  } else {
    this.deviceType = 'desktop';
  }
});

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

Это дает мне эту ошибку:

Свойство «отказаться от подписки» не существует для типа «Observable». Вы имели в виду "подписаться"?


person Mackelito    schedule 13.06.2018    source источник
comment
сначала вам нужно подписаться, присвоить это переменной, а затем вы можете отказаться от подписки.   -  person prady    schedule 13.06.2018


Ответы (2)


Вы можете использовать unsubscribe только на Subscription. Вы пытаетесь использовать это на Observable.

Если вы используете наблюдаемый внутри своего компонента с помощью канала async, вам не нужно отказываться от подписки. Это автоматически выполняется фреймворком.

Однако, если вы используете его внутри своего component.ts, то можно сделать это вот так. Есть и другие варианты, например, с использованием канала takeUntil:

private deviceObserver: Observable<BreakpointState> = 
                        this.breakpointObserver.observe([Breakpoints.XSmall]);

ngOnInit() {
  this.sub = this.deviceObserver.subscribe(result => {
    if (result.matches) {
      this.deviceType = 'mobile';
    } else {
      this.deviceType = 'desktop';
    }
  });
}

ngOnDestroy() {
 this.sub.unsubscribe();
}
person Poul Kruijt    schedule 13.06.2018
comment
Я пробовал это, но это сломало функции ... немного покопался, и если я сделаю это в ngOnDestroy, он сломается ... поэтому я переместил отписку в метод closeDialog, и это сработало! :) - person Mackelito; 13.06.2018
comment
это кажется маловероятным. Ваш код использует unsubscribe на наблюдаемом, вы не должны этого делать :), но сохраните ссылку на подписку (или используйте takeUntil) - person Poul Kruijt; 13.06.2018
comment
См. Мой обновленный вопрос (отсутствовал код, ха-ха) .. также опубликовал рабочий код в качестве ответа. Я думаю, что что-то не так, когда я открываю OverlayRef cdk и прикрепляю компонент к ComponentPortal - person Mackelito; 13.06.2018
comment
Код в вашем ответе использует ссылку на подписку, а код в вашем вопросе - нет. Я не вижу причин, по которым использование ссылки на подписку не будет работать в ngOnDestroy - person Poul Kruijt; 13.06.2018
comment
Что ж, я тоже, но код document.addEventListener ('keydown' ... работает только при первом нажатии клавиши, когда я добавляю ngOnDestroy (с подпиской / отказом от подписки или без нее) - person Mackelito; 13.06.2018
comment
почему бы вам не использовать (keydown)? Причина, по которой он работает только один раз, вероятно, заключается в том, что вы прикрепляете его к некоторому хуку ngOnInit, а элемент, к которому вы его прикрепляете, уничтожается и перестраивается после каждой проверки обнаружения углового изменения. Если он находится внутри *ngFor, вы должны использовать trackBy функциональность - person Poul Kruijt; 13.06.2018
comment
не уверен, что вы имеете в виду .. (это не нажатие клавиши в компоненте, а в службе) - person Mackelito; 13.06.2018

По какой-то причине отписка в ngOnDestroy сломала приложение ... Вот как я решил это:

private deviceObserver: Observable<BreakpointState> = this.breakpointObserver.observe([Breakpoints.XSmall]);
private breakpointObserverSubscription: Subscription;


// in ngOnInit()
this.breakpointObserverSubscription = this.deviceObserver.subscribe(result => {
  if (result.matches) {
    this.deviceType = 'mobile';
  } else {
    this.deviceType = 'desktop';
  }
});

public closeSearch() {
 this.onClose.apply();
 this.breakpointObserverSubscription.unsubscribe();
}
person Mackelito    schedule 13.06.2018