我正在尝试使用以下代码从外部服务器获取一些json数据:
ionViewDidLoad(){
console.log("user-detail page loaded");
}
fetchData(){
let loadingPopup = this.loadingCtrl.create({
content: 'Please wait...'
});
loadingPopup.present();
let user_data = "";
this.url = this.navParams.get("url");
return new Promise(resolve => {
this.http.post(this.url, null)
.subscribe(data => {
resolve( data );
loadingPopup.dismiss();
});
});
}
ionViewDidEnter(){
this.fetchData().then(data => {
this.user = JSON.parse(data._body);
});
console.log(this.user);
}
console.log(this.user)
的输出未定义。我想知道我哪里出错了。
答案 0 :(得分:1)
这种行为是预期的,因为您必须等待从服务器返回HTTP响应。我相信您知道,Promises
和Observables
是异步,因此在您的示例中,您等待响应时仍会执行其余代码服务器。
仅仅因为它在你的控制器中未定义,生命周期钩子并不一定意味着你无法从你的视图中访问它。但是,为了防止视图中出现错误,您可以在视图中使用ngIf
以确保在加载特定元素之前数据存在:
<p *ngIf="user">{{ user.displayName}}</p>
您还可以使用safe navigation operator(?
):
<p>{{ user?.displayName}}</p>
作为旁注,我建议坚持使用promises或observables来处理你的HTTP请求,因为我看到你正在将两者结合起来。您还可以考虑将HTTP请求移动到单独的服务文件中,然后将该服务注入控制器。这种模式有助于在应用程序开始增长时保持代码的可管理性。基于您的代码的Here is an example这种模式:
<强> api.service.ts 强>
import { Http } from '@angular/http';
import { Injectable } from '@angular/core';
import { Observable } from "rxjs/Observable";
import 'rxjs/add/operator/map';
@Injectable()
export class ApiService {
constructor(private http: Http) {}
fetchData(url: string): Observable<any> {
return this.http.get(url)
.map(data => data.json());
}
}
<强> your.comonent.ts 强>
constructor(private api: ApiService, private loadingCtrl: LoadingController) {
console.group('LifeCycle');
}
ionViewDidLoad() {
// will be undefined
console.log("ionViewDidLoad", this.launch);
}
ionViewDidEnter() {
this.fetchDataFromService();
// will be undefined
console.log('ionViewDidEnter', this.launch);
}
fetchDataFromService() {
let loadingPopup = this.loadingCtrl.create({
content: 'Please wait...'
});
loadingPopup.present();
//let user_data = "";
this.url = 'https://api.spacexdata.com/v2/launches/latest';
this.api.fetchData(this.url).subscribe(data => {
console.log('Server Response', data);
this.launch = data;
loadingPopup.dismiss();
},
(e:Error) => console.log(e));
}