typescript 使用 Ionic v2 在离开页面之前发出警报(导航回)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37955114/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:35:27  来源:igfitidea点击:

Alert before leaving page (navigate back) with Ionic v2

angulartypescriptionic-frameworkionic2ionic3

提问by Anders

How do you show an alert, that the user must close, before going back to the previous page? I'm using the standard <ion-navbar *navbar>arrow button.

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

I tried hooking into the NavControllerevent ionViewWillLeavelike this, but it doesn't work:

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

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

This shows the alert, but doesn't go back once it is closed. If I comment it out, the back button works fine.

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

采纳答案by sebaferreras

UPDATE

更新

As of Ionic2 RC, now we can use Nav Guards.

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

In some cases, a developer should be able to control views leaving and entering. To allow for this, NavController has the ionViewCanEnter and ionViewCanLeave methods. Similar to Angular 2 route guards, but are more integrated with NavController

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

So now we can do something like this:

所以现在我们可以做这样的事情:

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();
}

I prefer to use the this.showAlertMessageproperty, so we can have more control over when we need to show the alert if the user tries to exit the page. For instance, we may have a form in the page, and if the user didn't make any changes, we don't want to show the alert (this.showAlertMessage = false) and if the form was actually changed, we want to show the warning (this.showAlertMessage = true)

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



OLD ANSWER

旧答案

After a few hours struggling with this, I've found the solution.

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

One issue that I had to face is that the ionViewWillLeaveis executed also when the alertis closed so that makes things more complicated (when the viewis about to be closed because you pressed the back button, the alertshows up, but when you click ok, that fires the event again and opens the alertagain and so on...).

我不得不面对的一个问题是,在关闭ionViewWillLeave时也会执行 ,alert从而使事情变得更加复杂(当view由于按下后退按钮而即将关闭时,alert显示出现,但是当您单击ok 时,会触发事件再次打开alert,等等......)。

Another thing to keep in mind is that ActionSheetsand Alertsget added to the navigation stack, so this.nav.pop()instead of removing the current view from the stack, removes the alert(and because of that we may feel it's not working properly).

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

That being said, the solution I've found is:

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

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();
        });
    }


  }

So:

所以:

  • I use a confirmedExitvariable to know if you already clicked the ok button (so you confirmed you wanted to exit the page, and with that I know that the next time the ionViewWillLeaveevent is fired, I don't have to show the alert)
  • In the exitPagemethod, first I do this.nav.remove()to remove the alertfrom the stack, and once that's done, we do the this.nav.pop()to go back to the previous page.
  • 我使用一个confirmedExit变量来知道您是否已经单击了 ok 按钮(因此您确认要退出页面,并且我知道下次ionViewWillLeave触发事件时,我不必显示alert
  • exitPage方法中,首先我从堆栈中this.nav.remove()删除alert,完成后,我们this.nav.pop()返回上一页。


回答by Bo?tjan Pi?ler

The accepted solution doesn't work in RC3, here's a new one using Nav Controller's Nav Guard:

已接受的解决方案在 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();
  })
}

If you are navigating using push() on the nav controller, you also need to do a catch on it otherwise it will throw an unhandled error:

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

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

回答by zer09

this is my version of Bostjananswer, without throwing unhandled exception.

这是我的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();
    });
}