web-dev-qa-db-fra.com

Alerte avant de quitter la page (revenir en arrière) avec Ionic v2

Comment affichez-vous une alert, que l'utilisateur doit fermer avant de revenir à la page précédente? J'utilise le bouton-flèche <ion-navbar *navbar> standard .

J'ai essayé de m'accrocher à l'événement NavControllerionViewWillLeave comme ceci, mais cela ne fonctionne pas:

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

Cela montre l'alerte, mais ne retourne pas une fois qu'elle est fermée. Si je commente, le bouton de retour fonctionne bien.

9
Anders

METTRE &AGRAVE; JOUR

Depuis Ionic2 RC, nous pouvons maintenant utiliser Nav Guards .

Dans certains cas, un développeur devrait pouvoir contrôler les vues qui partent et en entrant. Pour ce faire, NavController dispose de ionViewCanEnter et de méthodes ionViewCanLeave. Similaire à Angular 2 gardes de route, mais sont plus intégré avec NavController

Alors maintenant, nous pouvons faire quelque chose comme ceci:

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

Je préfère utiliser la propriété this.showAlertMessage afin que nous puissions avoir un meilleur contrôle sur le moment où nous devons afficher l'alerte si l'utilisateur tente de quitter la page. Par exemple, nous pouvons avoir un formulaire dans la page et si l'utilisateur n'a apporté aucune modification, nous ne voulons pas afficher l'alerte (this.showAlertMessage = false) et si le formulaire a été modifié, nous voulons afficher l'avertissement ( this.showAlertMessage = true)


ANCIENNE RÉPONSE

Après quelques heures de travail avec cela, j'ai trouvé la solution. 

Un problème auquel j’ai dû faire face est que la ionViewWillLeave est exécutée également lorsque la alert est fermée, ce qui complique les choses (lorsque la view est sur le point de se fermer car vous avez appuyé sur le bouton Précédent, la alert s’affiche, mais lorsque ok, qui déclenche à nouveau l'événement et ouvre à nouveau la alert et ainsi de suite ...).

Une autre chose à garder à l'esprit est que ActionSheets et Alerts sont ajoutés au navigation stack, donc this.nav.pop() au lieu de supprimer la vue actuelle de la pile, supprime la alert (et à cause de cela nous pouvons penser qu'elle ne fonctionne pas correctement).

Cela étant dit, la solution que j'ai trouvée est la suivante:

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


  }

Alors:

  • J'utilise une variable confirmedExit pour savoir si vous avez déjà cliqué sur le bouton ok (vous avez donc confirmé que vous vouliez quitter la page et, avec cela, je sais que la prochaine fois que l'événement ionViewWillLeave est déclenché, je n'ai pas à afficher la alert).
  • Dans la méthode exitPage, je fais d'abord this.nav.remove() pour supprimer alert de la pile, puis une fois que cela est fait, nous faisons this.nav.pop() pour revenir à la page précédente.

7
sebaferreras

La solution acceptée ne fonctionne pas dans RC3, en voici une nouvelle utilisant Nav Controller 's 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();
  })
}

Si vous naviguez à l'aide de Push () sur le contrôleur de navigation, vous devez également effectuer une capture dessus, sinon une erreur non gérée sera générée:

this.navCtrl.Push(SomePage).catch(() => {});
12
Boštjan Pišler

c’est ma version de Bostjan answer, sans lancer d’exception non gérée.

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