我是Angular2中的新手,需要Observables的帮助。
我有网络应用程序,从远程资源获取一些数据并将其显示给用户。
问题是我应该使用http获取数据,将其存储在本地,然后由其他组件使用。
我已尝试过下一个方案:
data.ts
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class Airports {
private airportsUrl: string;
private cities: any;
private countries: any;
private routes: any;
private rawData: Observable<any>;
private errorMessage: any;
constructor(private http: Http) {
this.airportsUrl = '';
}
public get Cities() {
this.serverData.publishLast().refCount().subscribe(
data => this.cities = JSON.stringify(data)
);
return this.cities;
}
public get Countries() {
this.serverData.publishLast().refCount().subscribe(
data => this.countries = JSON.stringify(data)
);
return this.countries;
}
public get Routes() {
this.serverData.publishLast().refCount().subscribe(
data => this.routes = JSON.stringify(data)
);
return this.routes;
}
private init() {
this.serverData
.subscribe(
data => this.rawData = data,
error => this.errorMessage = <any> error
);
}
private get serverData() {
return this.http
.get(this.airportsUrl)
.map(this.parseData)
.catch(this.handleError);
}
private parseData(res: Response) {
let body = res.json();
return body;
}
private handleError (error: any) {
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg);
return Observable.throw(errMsg);
}
}
controler.ts
import '../../../public/css/styles.css';
import { Component, OnInit } from '@angular/core';
import { Airports } from './../data/data';
@Component({
providers: [Airports],
selector: 'destination-selector',
styleUrls: ['./../views/view.cityselector.css'],
templateUrl: './../views/view.cityselector.html',
})
export class CitySelector implements OnInit {
private cities: any;
private countries: any;
private routes: any;
constructor(private airports: Airports) { }
public ngOnInit() {
this.cities = this.airports.Cities;
this.countries = this.airports.Countries;
this.routes = this.airports.Routes;
}
}
view.cityselector.html
<main>
<div>Cities: {{ cities }}</div>
<div>Countries: {{ countries }}</div>
<div>Routes: {{ routes }}</div>
</main>
但是,使用这个方案我会调用http 3次(而不是1),并且此值{{ cities }}
未定义
那么,我如何从http中获取数据,将其转换为某个局部变量,然后使用本地数据,而不是始终调用新的http
答案 0 :(得分:0)
我认为这是因为Angular2中的http.get返回一个observable,它实际上不会获取任何数据,直到你调用subscribe为止。然后,每次您调用订阅时,您正在发出新的http请求。 我认为您应该立即订阅您的http.get并在服务中的变量中设置一次。然后让你的服务公共函数返回一个可观察的变量值。
This article by Cory Rylan was very helpful让我开始使用我正在处理的数据服务。
我做了类似这样的事情,我的服务是管理应用程序其余部分的数据数组。然后在使用数据的组件中,我将导入DataService并订阅dataService.getData()的返回值
@Injectable
export class DataService {
constructor(private http: Http){
this.loadData();
}
private _url = 'http://yoururlhere.com:3000/api/path';
public _appData$: BehaviorSubject<any[]> = new BehaviorSubject([]);
private appData:any[] = [];
loadData() {
console.log('Making HTTP request, loading data...');
this.http.get(this._url).map(this.extractData).subscribe(
data => {
this.appData = data;
this._appData$.next(data);
},
error => {
console.log(error);
}
);
}
addData(newData){
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({
headers: headers
});
this.http.post(this._url, newData, options).map(this.extractData).subscribe(data => {this.appData.push(data); this._appData$.next(this.appData);});
}
getData(){
return Observable.from(this._appData$);
}
private extractData(res: Response) {
let body = res.json();
return body || {};
}
}
&#13;