尝试防止两次订阅时出现ObjectUnsubscribedError [英] ObjectUnsubscribedError when trying to prevent subscribing twice
问题描述
我有一个服务和一个使用它的组件:
I have a Service and a component that uses it:
-
PagesService
-
PagesListComponent
PagesService
PagesListComponent
在PagesService
中,我有一个Pages
数组.我通过BehaviorSubject
通知它们都已订阅的数组中的更改.
In the PagesService
I have an array of Pages
. I notify changes in the array via a BehaviorSubject
which both of them are subscribed to.
在bootstrap
中提供了PagesService
,以便仅共享一个实例.那是因为我需要保留数组,而不是每次需要时都下载页面.
The PagesService
are provided at bootstrap
, to have just one instance shared. That's because I need to keep the array, instead of downloading the pages everytime they are needed.
代码如下:
pages.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/Rx';
import { Http, Response } from '@angular/http';
import { Page } from './../models/page';
@Injectable() export class PagesService {
public pages$: BehaviorSubject<Page[]> = new BehaviorSubject<Page[]>([]);
private pages: Page[] = [];
constructor(private http: Http) { }
getPagesListener() {
return this.pages$;
}
getAll() {
this.http.get('/mockups/pages.json').map((res: Response) => res.json()).subscribe(
res => { this.resetPagesFromJson(res); },
err => { console.log('Pages could not be fetched'); }
);
}
private resetPagesFromJson(pagesArr: Array<any>) {
// Parses de Array<any> and creates an Array<Page>
this.pages$.next(this.pages);
}
}
pages_list.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router-deprecated';
import { BehaviorSubject } from 'rxjs/Rx';
import { PagesService } from '../../shared/services/pages.service';
import { GoPage } from '../../shared/models/page';
@Component({
moduleId: module.id,
selector: 'go-pages-list',
templateUrl: 'pages_list.component.html',
styleUrls: ['pages_list.component.css']
})
export class PagesListComponent implements OnInit {
pages$: BehaviorSubject<GoPage[]>;
pages: GoPage[];
constructor(private pagesService: PagesService, private router: Router) { }
ngOnInit() {
this.pages$ = this.pagesService.getPagesListener();
this.pages$.subscribe((pages) => { this.pages = pages; console.log(pages) });
this.pagesService.getAll();
}
ngOnDestroy() {
this.pages$.unsubscribe();
}
}
在第一次ononit上取消订阅onDestroy都可以正常工作.但是,当我返回列表并尝试再次订阅(以获取pages []的当前值并监听将来的更改)时,它会触发错误 EXCEPTION: ObjectUnsubscribedError
.
This works fine the first time, both the subscription onInit and de unsubscription onDestroy. But when I return to the list and try to subscribe again (to fetch the current value of pages[] and listen for future changes), it fires the error EXCEPTION: ObjectUnsubscribedError
.
如果我不取消订阅,那么每次我进入列表时,都会堆叠一个新的订阅,并且在接收到next()时会触发所有订阅.
If I don't unsubscribe, everytime I enter to the list, a new subscription is stacked, and all of them are fired when a next() is received.
推荐答案
我将以这种方式而不是直接通过主题获取订阅并取消订阅:
I would get the subscription and unsubscribe on it this way and not on the subject directly:
ngOnInit() {
this.pages$ = this.pagesService.getPagesListener();
this.subscription = this.pages$.subscribe((pages) => { // <-------
this.pages = pages; console.log(pages);
});
this.pagesService.getAll();
}
ngOnDestroy() {
this.subscription.unsubscribe(); // <-------
}
这篇关于尝试防止两次订阅时出现ObjectUnsubscribedError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!