【问题标题】:Alert before leaving page (navigate back) with Ionic v2使用 Ionic v2 离开页面(向后导航)之前发出警报
【发布时间】:2016-10-23 15:11:29
【问题描述】:

如何显示alert,用户必须关闭才能返回上一页?我使用的是标准的<ion-navbar *navbar> 箭头按钮

我尝试像这样挂钩NavController 事件ionViewWillLeave,但它不起作用:

ionViewWillLeave() {
  let alert = Alert.create({
    title: 'Bye',
    subTitle: 'Now leaving',
    buttons: ['OK']
  });
  this.nav.present(alert);
}

这会显示警报,但一旦关闭就不会返回。如果我将其注释掉,则返回按钮可以正常工作。

【问题讨论】:

    标签: angular typescript ionic-framework ionic2 ionic3


    【解决方案1】:

    这是我的 Bostjan 答案版本,没有抛出未处理的异常。

    ionViewCanLeave(): Promise<boolean> {
        return new Promise(resolve => {
            if (!this.formGroup.dirty) return resolve(true);
    
            this._alertCtrl.create({
                title: 'Confirm leaving',
                message: 'There is unsave work, do you like to continue leaving?',
                buttons: [{
                    text: 'Leave',
                    handler: () => {
                        resolve(true);
                    }
                }, {
                    text: 'Stay',
                    handler: () => {
                        resolve(false);
                    }
                }]
            }).present();
        });
    }
    

    【讨论】:

      【解决方案2】:

      更新

      从 Ionic2 RC 开始,现在我们可以使用 Nav Guards

      在某些情况下,开发人员应该能够控制视图离开和 进入。为此,NavController 具有 ionViewCanEnter 和 ionViewCanLeave 方法。类似于 Angular 2 路由守卫,但 与 NavController 更集成

      所以现在我们可以这样做:

      someMethod(): void {
          // ...
          this.showAlertMessage = true;
      }
      
      ionViewCanLeave() {
          if(this.showAlertMessage) {
              let alertPopup = this.alertCtrl.create({
                  title: 'Exit',
                  message: '¿Are you sure?',
                  buttons: [{
                          text: 'Exit',
                          handler: () => {
                              alertPopup.dismiss().then(() => {
                                  this.exitPage();
                              });         
                          }
                      },
                      {
                          text: 'Stay',
                          handler: () => {
                              // need to do something if the user stays?
                          }
                      }]
              });
      
              // Show the alert
              alertPopup.present();
      
              // Return false to avoid the page to be popped up
              return false;
          }
      }
      
      private exitPage() {
          this.showAlertMessage = false;
          this.navCtrl.pop();
      }
      

      我更喜欢使用this.showAlertMessage 属性,这样当用户尝试退出页面时,我们可以更好地控制何时需要显示警报。例如,我们可能在页面中有一个表单,如果用户没有进行任何更改,我们不想显示警报 (this.showAlertMessage = false),如果表单实际上已更改,我们希望显示警告(this.showAlertMessage = true


      老答案

      经过几个小时的努力,我找到了解决方案。

      我不得不面对的一个问题是ionViewWillLeave 也会在alert 关闭时执行,这使得事情变得更加复杂(当view 即将关闭时,因为您按下了返回按钮, alert 出现,但是当您单击 ok 时,会再次触发事件并再次打开 alert,依此类推...)。

      要记住的另一件事是ActionSheetsAlerts 被添加到navigation stack,所以this.nav.pop() 不是从堆栈中删除当前视图,而是删除alert(正因为如此我们可能会觉得它工作不正常)。

      话虽如此,我找到的解决方案是:

      import {Component} from '@angular/core';
      import {NavController, NavParams, Alert} from 'ionic-angular';
      
      @Component({
          templateUrl: 'build/pages/mypage/mypage.html',
      })
      export class MyPage{
      
          // ....
      
          confirmedExit: boolean = false;
      
          constructor(private nav: NavController, navParams: NavParams) {
              // ...
          }
      
          ionViewWillLeave() {
              if(!this.confirmedExit) {
                  let confirm = Alert.create({
                      title: 'Bye',
                      message: 'Now leaving',
                      buttons: [
                      {
                          text: 'Ok',
                          handler: () => {
                              this.exitPage();
                          }
                      }
                      ]
                  });
                  this.nav.present(confirm);
              }
          }
      
          public exitPage(){
              this.confirmedExit = true;
              this.nav.remove().then(() => {
                  this.nav.pop();
              });
          }
      
      
        }
      

      所以:

      • 我使用confirmedExit 变量来了解您是否已单击“确定”按钮(因此您确认要退出页面,并且我知道下次触发ionViewWillLeave 事件时,我不会'不必显示alert)
      • exitPage 方法中,首先我执行this.nav.remove() 以从堆栈中删除alert,完成后,我们执行this.nav.pop() 以返回上一页。

      【讨论】:

      • 添加自定义后退按钮并隐藏自动后退按钮不是更容易吗?
      • @BoštjanPišler 但是如果用户不使用那个新按钮,而是使用 android 物理后退按钮怎么办?
      • 啊啊,触摸 :)
      • 我实际上在让这个在 RC3 中工作时遇到问题,页面导航然后出现警报。有什么想法吗?
      • 是的,刚刚发布了与新答案相同的内容:)
      【解决方案3】:

      已接受的解决方案在 RC3 中不起作用,这是使用 Nav Controller 的 Nav Guard 的新解决方案:

      ionViewCanLeave(): Promise<void> {
        return new Promise((resolve, reject) => {
          let confirm = this.alertCtrl.create({
            title: 'Are you sure?',
            message: 'Bunnies will die :(',
            buttons: [{
              text: 'OK',
              handler: () => {
                resolve();
              },
            }, {
              text: 'Cancel',
              handler: () => {
                reject();
              }
            }],
          });
          confirm.present();
        })
      }
      

      如果您在导航控制器上使用 push() 进行导航,您还需要对其进行捕捉,否则会引发未处理的错误:

      this.navCtrl.push(SomePage).catch(() => {});
      

      【讨论】:

      • 我刚试过这个(RC3,最新的应用程序脚本),但是当 'OK' 工作时,'Cancel' 抛出:.\node_modules\@angular\core\src\error_handler.js:53 Error: Uncaught (in promise): false
      • 你说得对,在使用 push 或类似的情况下必须使用 catch,我编辑了答案,谢谢。
      • 这应该是公认的答案。 @Cocowalla ,隐式错误处理将添加到 v2.1.0
      • 使用 2.1.0,将返回类型更改为 Promise 否则会出现类型不匹配错误。除此之外,这是一种享受,干杯!
      • 谢谢,这是一个公认的答案。它对我有用。
      猜你喜欢
      • 2011-04-10
      • 2010-11-20
      • 1970-01-01
      • 2017-06-05
      • 2015-12-31
      • 2020-06-11
      • 2021-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多