我正在学习Ang2。我成功地运行了英雄教程。为了练习,我刚刚在主页面中添加了一个链接来获取一个新组件。有一个带有无线电台列表的json文件。以下是我的服务和组件:
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调用服务时没有收到Radio,我看到它成功并从JSON文件中获取所有记录。任何帮助将不胜感激。
答案 0 :(得分: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
当Angular2已经解析模板中的绑定时,null
仍然是<div>{{radios?.xxx}}</div>
。为避免错误,您可以使用安全导航(Elvis)运算符
.xxx
当radios
为null
时,Angular2不会尝试访问{{1}}。
答案 1 :(得分:1)
问题是您从服务中订阅了您的observable。您的服务应返回 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;
}
...
);
}