web-dev-qa-db-ja.com

Ionic v2でページを離れる前に警告(戻る))

前のページに戻る前にユーザーが閉じる必要があるalertをどのように表示しますか?標準を使用しています<ion-navbar *navbar>矢印ボタン

次のようにNavControllerイベントionViewWillLeaveにフックしてみましたが、機能しません:

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

これはアラートを示していますが、いったん閉じると元に戻りません。コメントアウトすると、戻るボタンが正常に機能します。

9
Anders

[〜#〜]更新[〜#〜]

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_)


古い回答

これに苦労して数時間後、私は解決策を見つけました。

私が直面しなければならない1つの問題は、ionViewWillLeaveが閉じているときにalertも実行されるため、状況が複雑になることです(viewが閉じようとしているとき[戻る]ボタンを押すと、alertが表示されますが、okをクリックすると、イベントが再度発生し、alertが再び開き、など...)。

もう1つ覚えておくべきことは、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変数を使用して、[OK]ボタンが既にクリックされているかどうかを確認します(ページを終了することを確認したので、次にionViewWillLeaveイベントが発生したときに、 alertを表示する必要はありません)
  • exitPageメソッドでは、最初にthis.nav.remove()を実行してスタックからalertを削除し、完了したらthis.nav.pop()を実行して前のページに戻ります。

8
sebaferreras

承認されたソリューションはRC3では機能しません。これは Nav Controller のナビゲーションガードを使用した新しいソリューションです。

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

これは私のバージョンの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();
    });
}
1
zer09