简体   繁体   English

angular 2 observable 重新订阅以重用数据

[英]angular 2 observable resubscribe to reuse data

I am trying to reuse cached data.我正在尝试重用缓存数据。 If there is no cached data then use http to get data.如果没有缓存数据,则使用 http 获取数据。 If there is cached data then use the cached data in observable.如果有缓存数据,则使用 observable 中的缓存数据。

here is the data service.ts这是数据 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);          
      }
  }
}

The http.get().map().subscribe() is always working. http.get().map().subscribe() 始终有效。 this._heroesObserver.isUnsubscribed always shows false. this._heroesObserver.isUnsubscribed 总是显示 false。

But when there is cached data this._heroesObserver.isUnsubscribed always shows true.但是当有缓存数据时 this._heroesObserver.isUnsubscribed 总是显示为真。

The component calls to this function from within ngOnInit()组件从 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.')
                         );
  }

Does that matter?那有关系吗? I think not.我想不是。 What can I do to make it work?我该怎么做才能让它发挥作用?

Updated the code to add .publishReplay(null,1).refCount() .更新了代码以添加.publishReplay(null,1).refCount()

Now the refCount increments and the isUnsubscribed always shows false.现在refCount增加并且isUnsubscribed总是显示 false。 However, the component still cannot get data.但是,该组件仍然无法获取数据。 The first time when there is no cached data console.log in the component prints all data correctly.第一次当组件中没有缓存数据时,console.log 会正确打印所有数据。 But when there is cached data, the console.log prints nothing.但是当有缓存数据时,console.log 不会打印任何内容。

Use publishReplay(1) to change your observable into a hot observable that will remember and replay the last value and supply it to late subscribers:使用 publishReplay(1) 将您的 observable 更改为一个 hot observable,它将记住并重放最后一个值并将其提供给迟到的订阅者:

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

The last replayed value is essentially the cached value, which gets replaced when a new http request is made最后重放的值本质上是缓存的值,它在发出新的 http 请求时被替换

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM