Angular 使用Ionic v2离开页面前发出警报(向后导航)

Angular 使用Ionic v2离开页面前发出警报(向后导航),angular,typescript,ionic-framework,ionic2,ionic3,Angular,Typescript,Ionic Framework,Ionic2,Ionic3,如何显示用户在返回上一页之前必须关闭的警报?我正在使用标准的箭头按钮 我尝试像这样连接到NavController事件ionViewWillLeave,但它不起作用: ionViewWillLeave() { let alert = Alert.create({ title: 'Bye', subTitle: 'Now leaving', buttons: ['OK'] }); this.nav.present(alert); } 这将显示警报,但在关闭后不

如何显示用户在返回上一页之前必须关闭的
警报
?我正在使用标准的
箭头按钮

我尝试像这样连接到
NavController
事件
ionViewWillLeave
,但它不起作用:

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

这将显示警报,但在关闭后不会返回。如果我把它注释掉,后退按钮工作正常。

更新

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

在某些情况下,开发人员应该能够控制视图的离开和关闭 套房。为此,NavController具有IonViewCanCenter和 IonViewCanLeaf方法。类似于有棱角的2个路线守卫,但 更集成导航控制器

现在我们可以这样做:

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.showartmessage=false
),如果表单确实更改了,我们想显示警告(
this.showartmessage=true


旧答案

经过几个小时的努力,我找到了解决办法

我必须面对的一个问题是,
警报
关闭时也会执行
ionViewWillLeave
,这使得事情变得更加复杂(当您按下后退按钮,
视图
即将关闭时,会显示
警报
,但当您单击确定时,会再次触发事件并再次打开
警报
,依此类推……)

另一件需要记住的事情是
操作表
警报
被添加到
导航堆栈
,因此
this.nav.pop()
不是从堆栈中移除当前视图,而是移除
警报
(因此我们可能会感觉它工作不正常)

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

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


  }
因此:

  • 我使用一个
    confirmedxit
    变量来知道您是否已经单击了ok按钮(因此您确认要退出页面,这样我就知道下次触发
    ionViewWillLeave
    事件时,我不必显示
    警报
  • exitPage
    方法中,首先我执行
    this.nav.remove()
    从堆栈中删除
    警报
    ,完成后,我们执行
    this.nav.pop()
    返回上一页


接受的解决方案在RC3中不起作用,这里有一个新的解决方案,使用的是的导航卫士:

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

这是我的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();
    });
}
ionViewCanLeave():承诺{
返回新承诺(解决=>{
如果(!this.formGroup.dirty)返回解析(true);
这是。\u alertCtrl.create({
标题:“确认离开”,
消息:“有未保存的工作,是否继续离开?”,
按钮:[{
文字:'离开',
处理程序:()=>{
决心(正确);
}
}, {
文字:'停留',
处理程序:()=>{
决议(假);
}
}]
}).present();
});
}

添加自定义后退按钮并隐藏自动后退按钮不是更容易吗?@BoštjanPišler但如果用户不使用新按钮,而是使用android物理后退按钮,该怎么办?啊,touché:)我在RC3中实际遇到了问题,页面会导航,然后会显示警报。有什么想法吗?是的,我刚刚发布了一个新的答案:)我刚刚尝试了这个(RC3,最新的应用程序脚本),但是当“OK”起作用时,“Cancel”抛出:
\node\u modules\@angular\core\src\error\u handler.js:53错误:Uncaught(in promise):false
你是对的,如果使用推送或类似的方式,我会编辑答案,谢谢。这应该是公认的答案@Cocowalla,隐式错误处理将添加到v
2.1.0
中,使用2.1.0,将返回类型更改为Promise,否则会出现类型不匹配错误。除此之外,这是一种享受,干杯!谢谢,这是一个公认的答案。这对我有用。
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();
    });
}