【问题标题】:Ionic 3 NavController does not pop the view instead creates a new oneIonic 3 NavController 不会弹出视图而是创建一个新视图
【发布时间】:2018-04-02 21:23:51
【问题描述】:

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>

【问题讨论】:

  • 有人遇到过类似的问题吗?
  • 您能在 stackblitz.com 上重现您的问题吗?
  • @duannx 我尝试设置项目,但它有太多依赖项需要解决。我可以通过其他方式分享我的代码吗?
  • 如果你可以重现你的问题,那意味着你知道你的问题来自哪里,不需要添加所有的依赖和页面。在某些情况下,当您这样做时,您可以自己找到答案。
  • 它需要 Firebase 设置,这是棘手的部分。

标签: ionic-framework firebase-realtime-database ionic3 angularfire2 ionic-view


【解决方案1】:

取消订阅订阅者似乎可以解决问题。 HomePage 视图有未取消订阅的订阅者。我将 Observable Subscriptions 添加到数组中,并按照下面的代码取消订阅。

  ionViewWillLeave(){
    this.subscriptions.forEach(item=>{
      item.unsubscribe();
    });
  }

【讨论】:

    【解决方案2】:

    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。

    【讨论】:

    • 我试过了,但没有用。请参阅上面的更新代码。 ionViewDidEnter 根据离子文档应该没问题,问题是它执行了两次,因为在点击保存按钮后再次创建视图。
    • 你检查过视图堆栈吗?检查 navCtrl 以查看堆栈中的下一个视图。
    • 我相信你已经读过这个ionicframework.com/docs/api/navigation/NavController/…。我在您的代码中找不到您如何注入 navController?在该链接中,您将找到如何将根导航控制器传递给子视图。我不确定,因为我只有您的部分代码要分析,但我猜这个问题与您进行导航的方式有关。
    • 我根据文档使用简单的推送和弹出。我已经更新了代码
    猜你喜欢
    • 1970-01-01
    • 2012-11-18
    • 2018-03-21
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 2021-03-09
    • 1970-01-01
    相关资源
    最近更新 更多