1

我是 Angular2 的新手,需要 Observables 方面的帮助。

我有网络应用程序,它从远程资源中获取一些数据并将其显示给用户。

问题是我应该使用 http 获取数据,将其存储在本地,然后由其他组件使用。

我尝试了下一个方案:

数据.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);
}
}

控制器.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

4

1 回答 1

0

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

Cory Rylan 的这篇文章很有帮助,让我开始着手我正在研究的数据服务。

我做了这样的事情,我的服务正在为应用程序的其余部分管理一组数据。然后在使用数据的组件中,我将导入 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 || {};
  }
}

于 2016-10-19T20:38:32.560 回答