2016-06-28 12 views
12

私はサービスと、それを使用するコンポーネントを持っています。私はBehaviorSubjectを介して配列の変更を通知し、両方とも購読しています。ObjectUnsubscribedErrorは二回

PagesServiceは、bootstrapで提供され、インスタンスを1つだけ共有することができます。それは、必要なときにいつでもページをダウンロードするのではなく、配列を保持する必要があるからです。これは、両方の、細かい初めての作品

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。しかし、私がリストに戻って再び購読しようとすると(ページ[]の現在の値を取り出して将来の変更を聞くために)、はエラーEXCEPTION: ObjectUnsubscribedErrorを発生させます。

私が購読を停止した場合、リストに入るたびに、新しい購読が積み重ねられ、next()が受信されるとすべてが中止されます。

答えて

30

私が直接被写体にサブスクリプションを取得し、それにこの方法を退会していないでしょう。

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

なぜ注射された被験者のリファレンスに直接加入していないのですか? –

5

.subscribeは()あなたが を解除するためにこれを使用する必要があります

  • スクリプションを返します


親にはreloadSubject:Subjectがあります。

  • child1の - "WORKS" - - >退会者の彼の加入

    ngOnInit{ 
        sub: Subscription = parent.subscribe(); 
    } 
    onDestroy{ 
        this.sub.unsubscribe(); 
    } 
    


    child2の - "動かない">

child1のをサブスクライブ - >は

  • child2のは、サブスクライブ - >すべての親を解約する

    ngOnInit{ 
        parent.subscribe(); 
    } 
    
    onDestroy{ 
        parent.unsubscribe(); 
    } 
    

    親に対してunsubscribeを呼び出すと、両方の子どもがなくなります。
    あなたがから入手した購読を購読解除する場合。subscribe() 1人の子供のみが退会されます。

    私が間違っている場合は、私を修正してください!