2016-10-19 16 views
0

Я новичок в Angular2 и нуждаюсь в помощи с Observables.Наблюдаемая цепь в Угловом 2

У меня есть веб-приложение, которое получает некоторые данные из удаленного ресурса и показывает их пользователям.

Проблема в том, что я должен получать данные с помощью 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, Stroe него в некоторой локальной переменной и использовать локальный данные после этого, вместо этого всегда вызываются всегда новые http

+0

http://stackoverflow.com/questions/36271899/what -Использовать-правильно-путь-к-доля-результат-of-an-angular-2-http-network-call-in –

ответ

0

Я думаю, это связано с тем, что http.get в Angular2 возвращает наблюдаемое, которое фактически не получает никаких данных, пока вы не позвоните на него. Затем каждый раз, когда вы звоните, подписывается на него, вы делаете новый 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 || {}; 
 
    } 
 
}

+0

Но как я могу это сделать? Можете ли вы привести мне пример? –

Смежные вопросы