在数据有机会加载之前的 Ionic 2 视图渲染(和错误)
Ionic 2 view rendering (and erroring) before data has chance to load
我正在编写我的第一个 Ionic 2 应用程序,并且正在努力解决我在 Ionic 1 中不必担心的事情。
我有一个列表视图,其中列出了从 API 中获取的项目。这很好用。当您单击列表视图中的项目时,您会转到详细视图(这会进行另一个 ajax 调用以获取更多详细信息)。此视图在 ajax 调用完成之前呈现,我真的不确定为什么。
服务:
import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/Rx';
@Injectable()
export class DataService {
http: any;
baseUrl: String;
apiKey: String;
constructor(http:Http) {
this.http = http;
this.baseUrl = 'http://localhost:8100/api';
this.apiKey = 'xxx';
}
getList(token, page) {
return this.http.get(this.baseUrl + '/list?key=' + this.apiKey + '&token=' + token + '&page=' + page + '&per_page=20')
.map(res => res.json());
}
getDetails(token, ref) {
return this.http.get(this.baseUrl + '/details/' + ref + '?key=' + this.apiKey + '&token=' + token)
.map(res => res.json());
}
}
问题页面:
import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { Storage } from '@ionic/storage';
import { DataService } from '../../app/services/data.service';
@Component({
selector: 'details',
templateUrl: 'details.html'
})
export class DetailsPage {
token: string;
item: any;
ref: string;
constructor(public navCtrl: NavController, private dataService:DataService, private storage: Storage, public params:NavParams) {
this.ref = params.get('ref');
}
getDetail(token, ref) {
this.dataService.getDetails(token, ref).subscribe(
data => {
// this completes after the view has rendered, so the view errors
this.item = data;
console.log('this.item = ');
console.log(this.item);
},
err => {
console.log(err);
// handle expired token and redirect
}
);
}
ngOnInit() {
console.log('on init ran...');
this.storage.get('token').then((val) => {
this.token = val;
this.getDetail(this.token, this.ref);
});
}
}
我的模板中的每个变量都出错,例如第一个是:
Runtime Error
Cannot read property 'ref' of undefined
我是不是遗漏了一些明显的东西,或者有更好的方法来解决这个问题吗?我找到的所有教程都在 class 中调用 ajax 而不是在不正确的服务中...
--- 编辑 ---
此处请求的是列表页面的导航推送:
viewDetailsPage(ref) {
this.navCtrl.push(DetailsPage, {
ref: ref
})
}
--- 编辑 2 ---
这里要求的是列表页面模板:
<ion-header>
<ion-navbar>
<ion-title>Items</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list>
<button ion-item *ngFor="let item of items" (click)="viewDetailsPage(item.reference)" icon-start>
<h2>{{item.reference}}</h2>
<p>{{item.type.title}}</p>
<ion-badge item-end>{{item.status.title}}</ion-badge>
</button>
</ion-list>
</ion-content>
以及详情页面模板:
<ion-header>
<ion-navbar>
<ion-title>Item</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<h4>{{item.reference}}</h4>
</ion-content>
在无法在 "popped" 页面的任何地方找到单个示例进行 ajax 调用后,我最终从列表页面进行了 getDetail ajax 调用并传递了数据到详细信息页面,如:
列表页面,点击列表项时:
viewDetailsPage(ref) {
this.DataService. getDetails(this.token, ref).subscribe(
data => {
this.item = data;
this.navCtrl.push(DetailsPage, {
item: this.item
})
},
err => {
console.log(err);
// handle expired token and redirect
}
);
}
感觉这是正确的做法,但希望对此进行一些确认。
----更新----
虽然这行得通,但我最终还是接受了公认的答案。
将{{item.reference}}
更改为{{item?.reference}}
或
item: any = {}
而不是 item: any
;
作为 ajax 调用之前的视图渲染,它尝试获取 item
的 reference
属性。由于 item
仍然是 any 类型而不是对象,因此它会抛出错误。
{{item?.reference}}
处理异步变量。
我正在编写我的第一个 Ionic 2 应用程序,并且正在努力解决我在 Ionic 1 中不必担心的事情。
我有一个列表视图,其中列出了从 API 中获取的项目。这很好用。当您单击列表视图中的项目时,您会转到详细视图(这会进行另一个 ajax 调用以获取更多详细信息)。此视图在 ajax 调用完成之前呈现,我真的不确定为什么。
服务:
import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/Rx';
@Injectable()
export class DataService {
http: any;
baseUrl: String;
apiKey: String;
constructor(http:Http) {
this.http = http;
this.baseUrl = 'http://localhost:8100/api';
this.apiKey = 'xxx';
}
getList(token, page) {
return this.http.get(this.baseUrl + '/list?key=' + this.apiKey + '&token=' + token + '&page=' + page + '&per_page=20')
.map(res => res.json());
}
getDetails(token, ref) {
return this.http.get(this.baseUrl + '/details/' + ref + '?key=' + this.apiKey + '&token=' + token)
.map(res => res.json());
}
}
问题页面:
import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { Storage } from '@ionic/storage';
import { DataService } from '../../app/services/data.service';
@Component({
selector: 'details',
templateUrl: 'details.html'
})
export class DetailsPage {
token: string;
item: any;
ref: string;
constructor(public navCtrl: NavController, private dataService:DataService, private storage: Storage, public params:NavParams) {
this.ref = params.get('ref');
}
getDetail(token, ref) {
this.dataService.getDetails(token, ref).subscribe(
data => {
// this completes after the view has rendered, so the view errors
this.item = data;
console.log('this.item = ');
console.log(this.item);
},
err => {
console.log(err);
// handle expired token and redirect
}
);
}
ngOnInit() {
console.log('on init ran...');
this.storage.get('token').then((val) => {
this.token = val;
this.getDetail(this.token, this.ref);
});
}
}
我的模板中的每个变量都出错,例如第一个是:
Runtime Error
Cannot read property 'ref' of undefined
我是不是遗漏了一些明显的东西,或者有更好的方法来解决这个问题吗?我找到的所有教程都在 class 中调用 ajax 而不是在不正确的服务中...
--- 编辑 ---
此处请求的是列表页面的导航推送:
viewDetailsPage(ref) {
this.navCtrl.push(DetailsPage, {
ref: ref
})
}
--- 编辑 2 ---
这里要求的是列表页面模板:
<ion-header>
<ion-navbar>
<ion-title>Items</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list>
<button ion-item *ngFor="let item of items" (click)="viewDetailsPage(item.reference)" icon-start>
<h2>{{item.reference}}</h2>
<p>{{item.type.title}}</p>
<ion-badge item-end>{{item.status.title}}</ion-badge>
</button>
</ion-list>
</ion-content>
以及详情页面模板:
<ion-header>
<ion-navbar>
<ion-title>Item</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<h4>{{item.reference}}</h4>
</ion-content>
在无法在 "popped" 页面的任何地方找到单个示例进行 ajax 调用后,我最终从列表页面进行了 getDetail ajax 调用并传递了数据到详细信息页面,如:
列表页面,点击列表项时:
viewDetailsPage(ref) {
this.DataService. getDetails(this.token, ref).subscribe(
data => {
this.item = data;
this.navCtrl.push(DetailsPage, {
item: this.item
})
},
err => {
console.log(err);
// handle expired token and redirect
}
);
}
感觉这是正确的做法,但希望对此进行一些确认。
----更新----
虽然这行得通,但我最终还是接受了公认的答案。
将{{item.reference}}
更改为{{item?.reference}}
或
item: any = {}
而不是 item: any
;
作为 ajax 调用之前的视图渲染,它尝试获取 item
的 reference
属性。由于 item
仍然是 any 类型而不是对象,因此它会抛出错误。
{{item?.reference}}
处理异步变量。