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ångionViewWillLeave-händelsen avfyras, behöver jag inte visaalert) - I
exitPage-metoden gör jag förstthis.nav.remove()för att ta bortalertfrån stacken, och när det är gjort, gör vithis.nav.pop()för att gå tillbaka till föregående sida.
