繁体   English   中英

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

[英]angular 2 observable resubscribe to reuse data

我正在尝试重用缓存数据。 如果没有缓存数据,则使用 http 获取数据。 如果有缓存数据,则使用 observable 中的缓存数据。

这是数据 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().map().subscribe() 始终有效。 this._heroesObserver.isUnsubscribed 总是显示 false。

但是当有缓存数据时 this._heroesObserver.isUnsubscribed 总是显示为真。

组件从 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总是显示 false。 但是,该组件仍然无法获取数据。 第一次当组件中没有缓存数据时,console.log 会正确打印所有数据。 但是当有缓存数据时,console.log 不会打印任何内容。

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

最后重放的值本质上是缓存的值,它在发出新的 http 请求时被替换

暂无
暂无

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

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