尝试阻止订阅两次时出现 ObjectUnsubscribedError [英] ObjectUnsubscribedError when trying to prevent subscribing twice

查看:24
本文介绍了尝试阻止订阅两次时出现 ObjectUnsubscribedError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个服务和一个使用它的组件:

I have a Service and a component that uses it:

  • 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.

PagesServicebootstrap 中提供,只共享一个实例.那是因为我需要保留数组,而不是每次需要时都下载页面.

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

这第一次运行良好,订阅 onInit 和取消订阅 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆