Angular 2中的可观察链

时间:2016-10-19 19:02:32

标签: angular observable angular2-observables

我是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

1 个答案:

答案 0 :(得分:0)

我认为这是因为Angular2中的http.get返回一个observable,它实际上不会获取任何数据,直到你调用subscribe为止。然后,每次您调用订阅时,您正在发出新的http请求。 我认为您应该立即订阅您的http.get并在服务中的变量中设置一次。然后让你的服务公共函数返回一个可观察的变量值。

This article by Cory Rylan was very helpful让我开始使用我正在处理的数据服务。

我做了类似这样的事情,我的服务是管理应用程序其余部分的数据数组。然后在使用数据的组件中,我将导入DataService并订阅dataService.getData()的返回值

&#13;
&#13;
@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;
&#13;
&#13;