angular - Varning innan du lämnar sidan (navigera tillbaka) med Ionic v2


Hur visar du en alert som användaren måste stänga innan de går tillbaka till föregående sida? Jag använder standard <ion-navbar *navbar> piltangent.

Jag försökte hooka in i NavController-händelsen ionViewWillLeave på detta sätt, men det fungerar inte:

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

Detta visar varningen, men går inte tillbaka när den stängs. Om jag kommenterar bort det fungerar bakåtknappen som den ska.

Svar #1

Den accepterade lösningen fungerar inte i RC3, här är en ny som använder Nav Controllers 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();
  })
}

Om du navigerar med push() på nav-kontrollern behöver du också göra en catch på den annars kommer det att kasta ett ohanterat fel:

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

Svar #2

UPPDATERING

Från och med Ionic2 RC kan vi nu använda Nav Guards.

I vissa fall bör en utvecklare kunna kontrollera vyer som lämnar och går in. För att möjliggöra detta har NavController metoderna ionViewCanEnter och ionViewCanLeave. Liknande Angular 2-routguards, men är mer integrerade med NavController

Så nu kan vi göra något sådant här:

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

Jag föredrar att använda egenskapen this.showAlertMessage, så att vi kan ha mer kontroll över när vi behöver visa varningen om användaren försöker lämna sidan. Till exempel kan vi ha ett formulär på sidan, och om användaren inte har gjort några ändringar vill vi inte visa varningen (this.showAlertMessage=false) och om formuläret faktiskt har ändrats vill vi visa varningen (this.showAlertMessage=true).

GAMMALT SVAR

Efter några timmars kamp med detta har jag hittat lösningen.

Ett problem som jag var tvungen att hantera är att ionViewWillLeave också körs när alert stängs, vilket gör saker mer komplicerade (när view håller på att stängas eftersom du tryckte på tillbaka-knappen, visas alert, men när du klickar på ok, triggas händelsen igen och alert öppnas igen och så vidare...).

En annan sak att ha i åtanke är att ActionSheets och Alerts läggs till i navigation stack, så this.nav.pop() tar bort alert istället för att ta bort den aktuella vyn från stacken (och på grund av det kan vi känna att det inte fungerar som det ska).

Det sagt, lösningen jag har hittat är:

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


  }

Så :

  • Jag använder en confirmedExit-variabel för att veta om du redan klickade på OK-knappen (så att du bekräftade att du ville lämna sidan, och med det vet jag att nästa gång ionViewWillLeave-händelsen avfyras, behöver jag inte visa alert)
  • I exitPage-metoden gör jag först this.nav.remove() för att ta bort alert från stacken, och när det är gjort, gör vi this.nav.pop() för att gå tillbaka till föregående sida.

Relaterade artiklar