2016-04-21 97 views
0

我想重用緩存的數據。如果沒有緩存數據,則使用http獲取數據。如果有緩存的數據,則使用可觀察的緩存數據。角2可觀察的重新訂閱重用數據

這裏是數據service.ts

import {Injectable} from 'angular2/core'; 
import {Http, Response, Headers, RequestOptions} from 'angular2/http'; 
import {Observable} from 'rxjs/Observable'; 
import {Observer} from 'rxjs/Observer'; 
import 'rxjs/add/operator/share'; 

import {Hero} from './hero'; 
//import {HEROES} from './mock-heroes'; 


@Injectable() 
export class HeroService { 
    private _baseUrl: string; 
    private _cachedHeroes; 

    private _heroesObserver: Observer<Hero[]>; 
    private _heroObserver: Observer<Hero>; 
    heroes$: Observable<Hero[]>; 
    hero$: Observable<Hero>; 
    public _dataStore: { heroes: Hero[], hero: Hero }; 

    constructor (private http: Http) { 
     this._dataStore = { heroes: [], hero: {_id: null, name: null} }; 
     this.heroes$ = new Observable(observer => this._heroesObserver = observer).share(); 
     this.hero$ = new Observable(observer => this._heroObserver = observer).share(); 
     this._baseUrl = 'http://localhost:8081/api/hero/'; // URL to web api 
    } 

    loadHeroes() { 
     if (this._dataStore.heroes.length === 0) { 
     this.http.get(`${this._baseUrl}readAll`) 
       .map(response => response.json()).publishReplay(null,1).refCount() 
       .subscribe(data => { 
            this._dataStore.heroes = data; 
            this._heroesObserver.next(this._dataStore.heroes); 
            }, 
          error => console.log('Could not load heroes.') 
          ); 
     } 
     else { 
     // Observable.of(this._dataStore.heroes) 
     this.heroes$.map(data =>this._dataStore.heroes) 
     .publishReplay(null,1).refCount() 
     .subscribe(data => { 
            this._dataStore.heroes = data; 
            this._heroesObserver.next(this._dataStore.heroes); 
            console.log(this.heroes$); 
            }, 
          error => console.log('Could not load heroes.') 
          ); 
     //console.log(this._heroesObserver);   
     } 
    } 
} 

的http.get()。圖()。認購()總是工作。 this._heroesObserver.isUnsubscribe始終顯示爲false。

但是,當存在緩存的數據時,this._heroesObserver.isUnsubscribed始終顯示爲true。

從內ngOnInit組件調用該函數()

ngOnInit() { 
    this._heroService.loadHeroes();  
    this.heroes = this._heroService.heroes$; 
    this.heroes.subscribe(data => { 
            data.forEach((h, i) => { 
             console.log(h); 
            }); 
            }, 
          error => console.log('Could not get hero.') 
         ); 
    } 

請問是怎麼回事?我想不是。 我能做些什麼才能使它工作?

更新了代碼以添加.publishReplay(null,1).refCount()

現在refCount增量和isUnsubscribed總是顯示錯誤。但是,該組件仍然無法獲取數據。第一次當組件中沒有緩存數據時,console.log會正確打印所有數據。但是,當有緩存的數據時,console.log不會打印任何內容。

回答

1

使用publishReplay(1)改變你觀察到的成熱時觀察到的,將記住和重播最後一個值,並將其提供給已故用戶:

import * as Rx from 'rxjs/Rx'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/publishReplay'; 

this.heroes$ = http.get(...).map(...).publishReplay(1).refCount(); 

this.heroes$.subscribe(...); 

最後的重播值基本上緩存值,在發出新的http請求時被替換

+0

我無法找到Observable或Subscriber的connect()方法嗎? – Shawn

+0

對不起,我使用的是較舊的API。它應該是publishReplay(),並使用refCount()或connect()。使用refCount()具有一旦所有訂戶都未訂閱就自動處置共享觀察值的好處。 – pixelbits

+0

組件仍然無法獲取數據?我更新了問題以添加代碼和說明。必須有一些我錯過的簡單東西。 – Shawn