2016-06-14 14 views
1

Я учу Ang2. Я успешно закончил учебник Hero. для практики я просто добавил ссылку на главной странице, чтобы получить новый компонент. есть json-файл со списком Radio Station. следующее мое обслуживание, а также компонент:Угловая 2 http service

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

Вы не можете получить данные таким образом, от асинхронных вызовов (что при использовании Promise или Observable). 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, потому что здесь мы хотим получить данные. Когда мы подписываемся, также выполняются map() звонки в getRadios. 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 еще null, когда Angular2 уже разрешает привязки в шаблоне. Чтобы избежать ошибок, вы можете использовать оператор безопасной навигации (Elvis)

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

Angular2 не пытается получить доступ .xxx пока radios является null.

+1

Благодарим вас за подробное объяснение. Я вижу намного лучше процесс. –

+0

Как я могу заставить службу вернуть Radio [], или мне нужно преобразовать ответ в Component? –

+0

Вы не предоставили класс «Радио» (или интерфейс), а также не то, как данные выглядят так, как вы получаете от наблюдаемого. Трудно сказать без полной информации. http://stackoverflow.com/questions/22885995/how-do-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» –

+1

'import {Observable} from 'rxjs/Observable';' –

+0

Merci Agha Mortez –

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