2016-06-14 212 views
1

我正在學習Ang2。我成功地運行了英雄教程。爲了練習,我只是在主頁面添加了一個鏈接來獲得一個新組件。有一個帶有電臺列表的json文件。以下是我的服務和組件:Angular 2 http服務

import { Radio } from '../models/radio'; 

import { Injectable } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 
import 'rxjs/Rx'; 

@Injectable() 
export /** 
* RadioService 
*/ 
    class RadioService { 
    radios: Radio[] = []; 
    len: Number = 0; 
    http: Http; 
    constructor(http: Http) { 
     this.http = http; 
    } 
    getRadios() { 
     console.log('Radios Service is being called'); 
     this.http.get('app/mock/FranceRadioJSON.json') 
      .map((res: Response) => res.json()) 
      .subscribe((rad: Radio[]) => {  // Succes 
       console.log('Radios Service Success'); 
       this.radios = rad; 
       this.len = rad.length; 
      } 

      , err => {// Failure 
       console.log('Radio Services Failure'); 
       console.error(err); 
      } 

      , // complete 
      () => { 
       console.log('Get Radios Complete'); 
       console.log('Records NB: ' + this.len); 
       console.log('radios nb: ' + this.radios.length) 
      } 
      ) 
      ; 
     return this.radios; 

    } 

和組件是:

import { Component, OnInit } from '@angular/core'; 
import { RouteParams } from '@angular/router-deprecated'; 
import { Radio } from '../../models/radio'; 
import { RadioService } from '../../services/radio.service'; 

@Component({ 
    selector: 'radio' 
    , templateUrl: 'app/html/radio.component.html' 
    , providers: [RadioService] 
}) 
export /** 
* RadioComponent 
*/ 
    class RadioComponent { 
    radios: Radio[] = []; 
    constructor(
     private radioservice: RadioService) { 
    } 
    getRadios() { 
     this.radios = this.radioservice.getRadios(); 
     console.log('radio component NB: ' + this.radios.length); 
    } 
    ngOnInit() { 
     this.getRadios() 


    } 
} 

的問題是服務的呼叫首先來了,也沒有收音機是而當服務回報用console.log調用我看到這是成功的,並從JSON文件獲取所有記錄。任何幫助將不勝感激。

回答

3

你不能得到數據從異步調用這種方式(這是當你使用PromiseObservable)。 Http返回和Observable。您需要subscribe(),並在您傳遞給subscribe(...)的回叫中獲得數據並將其分配給本地屬性。

而且例如,你如何解決這個問題:

getRadios我們不叫subscribe()和使用map()來代替。 map()返回一個Observable,它允許調用者獲取數據。 subscribe()返回一個Subscription不允許允許獲取響應數據,它只允許取消訂閱(這通常也很方便,但現在不行;-))。

getRadios() { 
    console.log('Radios Service is being called'); 
    return this.http.get('app/mock/FranceRadioJSON.json') 
     .map((res: Response) => res.json()) 
     .map((rad: Radio[]) => {  // Succes 
      console.log('Radios Service Success'); 
      this.radios = rad; 
      this.len = rad.length; 
     }); 
} 

我們在getRadios訂閱,因爲在這裏我們想要獲取數據。當我們訂閱時,getRadios中的map()調用也會被執行。 subscribe()使得Observable實際上做的工作:

getRadios() { 
    this.radios = this.radioservice.getRadios() 
     .subscribe((radios) => { 
      this.radios = radios; 
     } , err => {// Failure 
      console.log('Radio Services Failure'); 
      console.error(err); 
     } , // complete 
     () => { 
      console.log('Get Radios Complete'); 
      console.log('Records NB: ' + this.len); 
      console.log('radios nb: ' + this.radios.length) 
     }); 

    // executed before the HTTP get call to the server 
    // console.log('radio component NB: ' + this.radios.length); 
} 

由於數據不立即但只有當傳遞給subscribe(...)回調執行,你可以得到錯誤的綁定像

<div>{{radios.xxx}}</div> 

radios仍返回當Angular2已經解析了模板中的綁定時,它就會返回null。爲了避免錯誤,你可以使用安全的導航(貓王)運算符

<div>{{radios?.xxx}}</div> 

Angular2不會嘗試訪問.xxxradiosnull

+1

感謝您的詳細解釋。我看到更好的過程。 –

+0

如何強制服務返回Radio [],還是應該將組件中的響應轉換? –

+0

您沒有提供'Radio'類(或接口),也沒有提供數據看起來像從observable獲得的樣子。沒有完整的信息很難說清楚。 http://stackoverflow.com/questions/22885995/how-do-i-initialize-a-typescript-object-with-a-json-object可能是你在找什麼。 –

1

問題是您正在從您的服務中訂閱您的觀察值。你的服務應該返回一個Observable然後你Subscribe它從你的組件。

所以,你的服務應該是:

getRadios() : Observable<Radio[]> { 
    return this.http.get('app/mock/FranceRadioJSON.json') 
        .map((res: Response) => <Radio[]>res.json()) 
} 

而且您的組件:

getRadios() { 
    this.radios = this.radioservice.getRadios().subscribe(
     r => { 
      this.radios = r; 
     } 
     ... 
    ); 
} 
+0

必須導入哪個模塊才能包含Observable?我得到無法找到名稱'Observable' –

+1

'從{rxjs/Observable'進口{Observable};' –

+0

Merci Agha Mortez –