2016-06-21 60 views
8

Come si mostra un alert, che l'utente deve chiudere, prima di tornare alla pagina precedente? Sto usando lo standard <ion-navbar *navbar>pulsante freccia.Avviso prima di lasciare la pagina (tornare indietro) con Ionic v2

ho provato agganciando nella NavController evento ionViewWillLeave come questo, ma non funziona:

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

Questo mostra l'allarme, ma non torna indietro una volta che è chiuso. Se commento, il pulsante Indietro funziona correttamente.

risposta

6

UPDATE

A partire dal Ionic2 RC, ora possiamo usare Nav Guards.

In some cases, a developer should be able to control views leaving and entering. To allow for this, NavController has the ionViewCanEnter and ionViewCanLeave methods. Similar to Angular 2 route guards, but are more integrated with NavController

Così ora siamo in grado di fare qualcosa di simile:

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

preferisco usare la proprietà this.showAlertMessage, in modo che possiamo avere un maggiore controllo su quando abbiamo bisogno di mostrare l'avviso se l'utente tenta di esci dalla pagina Ad esempio, potremmo avere un modulo nella pagina e se l'utente non ha apportato alcuna modifica, non vogliamo mostrare l'avviso (this.showAlertMessage = false) e se il modulo è stato effettivamente modificato, vogliamo mostrare l'avviso (this.showAlertMessage = true)


risposta Old

Dopo qualche ora alle prese con questo, ho trovato la soluzione.

Un problema che ho dovuto affrontare è che il ionViewWillLeave viene eseguito anche quando il alert è chiuso in modo che rende le cose più complicate (quando il view sta per essere chiuso perché è stato premuto il pulsante Indietro, il alert si presenta, ma quando si fa clic su ok, l'evento viene nuovamente attivato e si apre nuovamente lo alert e così via ...).

Un'altra cosa da tenere a mente è che ActionSheets e Alerts vengono aggiunti al navigation stack, così this.nav.pop() invece di rimuovere la vista corrente dalla pila, rimuove il alert (e per questo noi possiamo sentire che non funziona correttamente).

Detto questo, la soluzione che ho trovato è:

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


    } 

Quindi:

  • Io uso una variabile confirmedExit per sapere se si è già fatto clic sul pulsante OK (in modo da voi ha confermato volevo uscire dalla pagina e con ciò so che la prossima volta che l'evento ionViewWillLeave viene attivato, non devo mostrare lo alert)
  • Nel metodo exitPage, prima I fare this.nav.remove() per rimuovere il alert dallo stack, e una volta fatto, facciamo il this.nav.pop() per tornare alla pagina precedente.

+1

Non sarebbe più semplice aggiungere un pulsante indietro personalizzato e nascondere quello automatico? –

+0

@ BoštjanPišler ma cosa succede se l'utente non usa quel nuovo pulsante, ma il pulsante fisico di Android? – sebaferreras

+0

aaah, touché :) –

10

La soluzione accettata non funziona in RC3, ecco una nuova utilizzando Nav Controller s' Nav Guardia:

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

Se state navigando tramite push() sul controller di navigazione, è inoltre necessario fare un errore altrimenti invierà un errore non gestito:

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

Ho appena provato questo (RC3, gli ultimi script di app), ma mentre 'OK' funziona, 'Annulla' getta: '. \ Node_modules \ @angular \ core \ src \ error_handler.js: 53 Errore: Uncaught (in promessa): false' – Cocowalla

+1

Hai ragione, in caso di utilizzo di push o simili, una cattura deve essere usato, ho modificato la risposta, grazie. –

+0

Questa dovrebbe essere la risposta accettata. @Cocowalla, la gestione implicita degli errori verrà aggiunta in v'2.1.0' –