问题描述
我有一个angular 2服务,可以从API提取数据该服务有3个订阅者(在组件"中定义),每个订阅者都对数据(不同的图)做其他事情
I have an angular 2 service that fetch data from an APIthis service has 3 subscribers (defined in Components) each doing something else with the data (different graphs)
我注意到我正在对API进行三个GET请求,而我要实现的是一个请求,订阅者将共享数据我研究了HOT和COLD可观察对象,并在可观察对象上尝试了.share(),但我仍在进行3个单独的调用
I'm noticing that I'm doing three GET requests to the API while what i want to achieve is one request and that the subscribers will share the dataI've looks into HOT and COLD observable and tried the .share() on the observable but I'm still doing 3 individual calls
更新,添加代码
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import {Observable} from 'rxjs/Rx';
// Import RxJs required methods
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { StationCompliance } from './model/StationCompliance';
@Injectable()
export class StationComplianceService {
private url = '/api/read/stations';
constructor(private http : Http) {
console.log('Started Station compliance service');
}
getStationCompliance() : Observable<StationCompliance []> {
return this.http.get(this.url)
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server Error'));
}
}
import { Component, OnInit } from '@angular/core';
import { CHART_DIRECTIVES } from 'angular2-highcharts';
import { StationComplianceService } from '../station-compliance.service';
@Component({
selector: 'app-up-down-graph',
templateUrl: './up-down-graph.component.html',
styleUrls: ['./up-down-graph.component.css']
})
export class UpDownGraphComponent implements OnInit {
graphData;
errorMessage: string;
options;
constructor(private stationService : StationComplianceService) { }
ngOnInit() {
this.getStationTypes();
}
getStationTypes(){
this.stationService.getStationCompliance()
.subscribe(
graphData => {
this.graphData = graphData;
this.options = {
chart : {type: 'pie',
plotShadow: true
},
plotOptions : {
showInLegend: true
},
title : {text: 'Up and Down devices'},
series: [{
data: this.processStationType(this.graphData)
}]
}
},
error => this.errorMessage = <any>error
);
}
其他两个组件几乎相同,它们只是显示其他图形
Other two components are almost the same, they just show other graph
推荐答案
我遇到了类似的问题,并使用Aran的建议引用了Cory Rylan的 Angular 2 Observable Data Services 博客文章.对我来说,关键是使用BehaviorSubject
.这是最终对我有用的代码片段.
I encountered a similar problem and solved it using Aran's suggestion to reference Cory Rylan's Angular 2 Observable Data Services blog post. The key for me was using BehaviorSubject
. Here's the snippets of the code that ultimately worked for me.
数据服务在初始化服务时创建一个内部BehaviorSubject
以将数据缓存一次.消费者使用subscribeToDataService()
方法访问数据.
The data service creates an internal BehaviorSubject
to cache the data once when the service is initialized. Consumers use the subscribeToDataService()
method to access the data.
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { Data } from './data';
import { properties } from '../../properties';
@Injectable()
export class DataService {
allData: Data[] = new Array<Data>();
allData$: BehaviorSubject<Data[]>;
constructor(private http: Http) {
this.initializeDataService();
}
initializeDataService() {
if (!this.allData$) {
this.allData$ = <BehaviorSubject<Data[]>> new BehaviorSubject(new Array<Data>());
this.http.get(properties.DATA_API)
.map(this.extractData)
.catch(this.handleError)
.subscribe(
allData => {
this.allData = allData;
this.allData$.next(allData);
},
error => console.log("Error subscribing to DataService: " + error)
);
}
}
subscribeToDataService(): Observable<Data[]> {
return this.allData$.asObservable();
}
// other methods have been omitted
}
成分:
组件可以在初始化时订阅数据服务.
Component:
Components can subscribe to the data service upon initialization.
export class TestComponent implements OnInit {
allData$: Observable<Data[]>;
constructor(private dataService: DataService) {
}
ngOnInit() {
this.allData$ = this.dataService.subscribeToDataService();
}
}
组件模板:
然后,模板可以根据需要使用异步管道在可观察对象上进行迭代.
Component Template:
The template can then iterate over the observable as necessary using the async pipe.
*ngFor="let data of allData$ | async"
每次在数据服务中的BehaviorSubject
上调用next()
方法时,
订户都会更新.
Subscribers are updated each time the next()
method is called on the BehaviorSubject
in the data service.
这篇关于Angular 2可观察到多个订阅者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!