簡體   English   中英

組件被銷毀並重新訪問后,訂閱在 ngOnInit function 中運行

[英]Subscription runs in ngOnInit function after Component is destroyed and Revisited

對於 Angular 組件和 rxjs 訂閱,我遇到了一個非常奇怪的情況。

我有以下ngOnInitngOnDestroy函數

ngOnInit() {
    zip(this.service.getMessage, this.service.getType)
      .pipe(takeUntil(this.componentDestroyed$))
      .subscribe(data => {
        const notification = new Notification(data[0], data[1]);
        this.notifications.push(notification);
    });
}

ngOnDestroy(): void {
    this.componentDestroyed$.next(true);
    this.componentDestroyed$.complete();
}

在服務文件中使用 Source 和 Subject 范例設置值后,訂閱處於活動狀態,如下所示:

private messageSource = new BehaviorSubject<string>('');
private message = this.messageSource.asObservable();
private typeSource = new BehaviorSubject<number>(-1);
private type = this.typeSource.asObservable();

...
...

set setMessage(message: string) {
  this.messageSource.next(message);
}

set setType(type: number) {
  this.typeSource.next(type);
}

正如預期的那樣,初始訂閱工作正常。 但是,離開組件並導航回同一個組件會在ngOnInit中再次運行zip訂閱,即使在離開時組件被破壞后也是如此。 如何防止這種情況發生? 我也嘗試過定義訂閱變量並調用unsubscribe 我難住了。

為了擴展我的評論,RxJS BehaviorSubject保存推送給它的當前值並在訂閱時立即發出它。 它還允許您在BehaviorSubject上使用唯一的getValue() function(或value getter),從而允許您同步檢索它持有的當前值。 雖然這個 getter 的使用通常是不受歡迎的。

因此,在您的情況下,當您路由回組件時,訂閱會發出兩個可觀察對象先前持有的值。 相反,您可以使用Subject保存值並且僅在將值推送到它之后才發出的主題。

private messageSource = new Subject<string>();
private message = this.messageSource.asObservable();
private typeSource = new Subject<number>();
private type = this.typeSource.asObservable();
...

我還建議您查看 RxJS ReplaySubject 這是一個更靈活的多播可觀察對象。 它接收要緩沖的通知數量,並在新訂閱時立即發出它們。

因此, ReplaySubject(1) (緩沖區 1)類似於BehaviorSubject ,只是它不需要默認值。 因此,如果您在尚未向其中推送任何內容時訂閱它,則它不會發出。

它對當前問題沒有幫助,但在您希望擁有 BehaviorSubject 的BehaviorSubject但不希望處理不必要的默認值的情況下可能會有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM