2016-06-14 248 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 –