Ionic 3 NavController 不会弹出视图而是创建一个新视图
Ionic 3 NavController does not pop the view instead creates a new one
ionViewDidLoad
函数似乎被调用了两次,这导致创建了 AddressPage 的多个视图。我已经对此进行了调试,看起来每当更新数据时都会创建新的视图实例。这种行为似乎只有在我使用 fireabse 保存地址时才会发生。如果我注释掉保存地址的代码,则不会创建新视图,并且应用程序会导航到上一个屏幕。
有什么办法可以避免这种情况?
我在 saveAddress 方法中尝试了 ViewCotnroller.dismiss()
和 NavController.pop()
,但似乎无法避免创建新视图。
@Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = HomePage;
constructor(platform: Platform, statusBar: StatusBar) {
platform.ready().then(() => {
statusBar.styleDefault();
statusBar.backgroundColorByHexString('#1572b5');
});
}
}
首页
import {NavController } from 'ionic-angular';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController, public firebaseProvider:
FirebaseProvider) {
}
//navigate to different view
navigate(){
this.navCtrl.push(AddressPage, {address:newAddress});
}
}
地址页
import {NavController } from 'ionic-angular';
@Component({
selector: 'page-address',
templateUrl: 'address.html'
})
export class AddressPage {
constructor(public navCtrl: NavController, public firebaseProvider:
FirebaseProvider, private navParams: NavParams) {
this.addressKey = this.navParams.get('key');
}
ionViewDidEnter(){
//load some data from server
}
saveAddress(){
//save data to server
this.firebaseProvider.saveAddress(newAddress);
//move back
this.navCtrl.pop();
}
}
使用 AngularFireDatabase 的 Firebase 提供程序
import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
@Injectable()
export class FirebaseProvider {
constructor(public afd: AngularFireDatabase) { }
saveAddress(address) {
this.afd.list('/addresses').push(address);
}
updateAddress(key,dataToUpdate){
return this.afd.list('addresses').update(key,dataToUpdate);
}
}
我也试过这个,但它有同样的问题。
this.firebaseProvider.saveAddress(newAddress).then(result => {
// loadingSpinner.dismiss();
this.navCtrl.pop();
});
this.firebaseProvider.updateAddress(this.addressKey, updateItems)
.then(() => {
// loadingSpinner.dismiss();
this.navCtrl.pop()
});
保存按钮HTML
<button type="button" ion-button full color="primary-blue" (click)='saveAddress()'>Save</button>
push 方法返回带有操作结果的承诺。我会像这样更改保存方法:
saveAddress(address) {
return this.afd.list('/addresses').push(address);
}
然后在控制器中我会这样改变它:
saveAddress(){
//save data to serve
this.firebaseProvider.saveAddress(newAddress).then(result => {
//do yours validations
this.navCtrl.pop();
});
}
有了这些,您就可以将页面导航到 Firebase 执行的结果。尝试一下这种方法,如果它不起作用请告诉我,无论如何我只会使用 oninit 加载数据一次,因为我猜你想这样做而不是 ionViewDidEnter。
看来取消订阅者可以解决问题。 HomePage 视图有未取消订阅的订阅者。我将 Observable 订阅添加到数组中并按照以下代码取消订阅。
ionViewWillLeave(){
this.subscriptions.forEach(item=>{
item.unsubscribe();
});
}
ionViewDidLoad
函数似乎被调用了两次,这导致创建了 AddressPage 的多个视图。我已经对此进行了调试,看起来每当更新数据时都会创建新的视图实例。这种行为似乎只有在我使用 fireabse 保存地址时才会发生。如果我注释掉保存地址的代码,则不会创建新视图,并且应用程序会导航到上一个屏幕。
有什么办法可以避免这种情况?
我在 saveAddress 方法中尝试了 ViewCotnroller.dismiss()
和 NavController.pop()
,但似乎无法避免创建新视图。
@Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = HomePage;
constructor(platform: Platform, statusBar: StatusBar) {
platform.ready().then(() => {
statusBar.styleDefault();
statusBar.backgroundColorByHexString('#1572b5');
});
}
}
首页
import {NavController } from 'ionic-angular';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController, public firebaseProvider:
FirebaseProvider) {
}
//navigate to different view
navigate(){
this.navCtrl.push(AddressPage, {address:newAddress});
}
}
地址页
import {NavController } from 'ionic-angular';
@Component({
selector: 'page-address',
templateUrl: 'address.html'
})
export class AddressPage {
constructor(public navCtrl: NavController, public firebaseProvider:
FirebaseProvider, private navParams: NavParams) {
this.addressKey = this.navParams.get('key');
}
ionViewDidEnter(){
//load some data from server
}
saveAddress(){
//save data to server
this.firebaseProvider.saveAddress(newAddress);
//move back
this.navCtrl.pop();
}
}
使用 AngularFireDatabase 的 Firebase 提供程序
import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
@Injectable()
export class FirebaseProvider {
constructor(public afd: AngularFireDatabase) { }
saveAddress(address) {
this.afd.list('/addresses').push(address);
}
updateAddress(key,dataToUpdate){
return this.afd.list('addresses').update(key,dataToUpdate);
}
}
我也试过这个,但它有同样的问题。
this.firebaseProvider.saveAddress(newAddress).then(result => {
// loadingSpinner.dismiss();
this.navCtrl.pop();
});
this.firebaseProvider.updateAddress(this.addressKey, updateItems)
.then(() => {
// loadingSpinner.dismiss();
this.navCtrl.pop()
});
保存按钮HTML
<button type="button" ion-button full color="primary-blue" (click)='saveAddress()'>Save</button>
push 方法返回带有操作结果的承诺。我会像这样更改保存方法:
saveAddress(address) {
return this.afd.list('/addresses').push(address);
}
然后在控制器中我会这样改变它:
saveAddress(){
//save data to serve
this.firebaseProvider.saveAddress(newAddress).then(result => {
//do yours validations
this.navCtrl.pop();
});
}
有了这些,您就可以将页面导航到 Firebase 执行的结果。尝试一下这种方法,如果它不起作用请告诉我,无论如何我只会使用 oninit 加载数据一次,因为我猜你想这样做而不是 ionViewDidEnter。
看来取消订阅者可以解决问题。 HomePage 视图有未取消订阅的订阅者。我将 Observable 订阅添加到数组中并按照以下代码取消订阅。
ionViewWillLeave(){
this.subscriptions.forEach(item=>{
item.unsubscribe();
});
}