2016-12-29 4 views
14

Comment puis-je gérer l'action du bouton arrière sur Ionic 2?Comment gérer le bouton retour sur Ionic 2

Je veux être capable de savoir quoi faire en fonction de la page affichée à l'utilisateur.

Je n'ai pas trouvé de bonne réponse à cette question, mais après un moment, je me suis dit que c'était une façon de le faire. Je vais partager avec vous tous.

Merci

+0

Pourquoi diable les réponses ci-dessous à cette question est si dur et ne se sentent pas comme la mise en œuvre? :(Quelle serait la manière la plus simple et la plus simple? –

Répondre

22

Voici comment je l'ai fait:

Dans tous les composants de la page, j'ai créé une fonction appelée backButtonAction(), qui exécutera un code personnalisé pour chaque page.

code:

import { Component } from '@angular/core'; 
import { Platform, NavController, ModalController } from 'ionic-angular'; 
import { DetailsModal } from './details'; 

@Component({ 
    selector: 'page-appointments', 
    templateUrl: 'appointments.html' 
}) 
export class AppointmentsPage { 
    modal: any; 

    constructor(private modalCtrl: ModalController, public navCtrl: NavController, public platform: Platform) { 
     // initialize your page here 
    } 

    backButtonAction(){ 
     /* checks if modal is open */ 
     if(this.modal && this.modal.index === 0) { 
      /* closes modal */ 
      this.modal.dismiss(); 
     } else { 
      /* exits the app, since this is the main/first tab */ 
      this.platform.exitApp(); 
      // this.navCtrl.setRoot(AnotherPage); <-- if you wanted to go to another page 
     } 
    } 

    openDetails(appointment){ 
     this.modal = this.modalCtrl.create(DetailsModal, {appointment: appointment}); 
     this.modal.present(); 
    } 
} 

Et dans le app.component.ts, j'ai utilisé la méthode platform.registerBackButtonAction pour enregistrer un rappel qui sera appelé à chaque fois que le bouton de retour est cliqué. A l'intérieur je vérifie si la fonction backButtonAction existe dans la page courante et l'appelle, si elle n'existe pas, il suffit d'aller dans l'onglet principal/premier.

On pourrait simplifier cela s'ils n'avaient pas besoin d'effectuer des actions personnalisées pour chaque page. Vous pouvez simplement afficher ou quitter l'application. Je l'ai fait de cette façon parce que j'avais besoin de vérifier si le modal était ouvert sur cette page particulière.

code:

platform.registerBackButtonAction(() => { 
    let nav = app.getActiveNav(); 
    let activeView: ViewController = nav.getActive(); 

    if(activeView != null){ 
     if(nav.canGoBack()) { 
     nav.pop(); 
     }else if (typeof activeView.instance.backButtonAction === 'function') 
     activeView.instance.backButtonAction(); 
     else nav.parent.select(0); // goes to the first tab 
    } 
    }); 

si la page en cours est la première languette, l'application se ferme (comme défini dans la méthode backButtonAction).

+0

laissez nav = app.getActiveNav(); ** quelle est cette application ** –

+1

Son une instance du composant 'App', importé de' ionic-angular' –

+0

i Je suis en utilisant les onglets et sidemenu dans mon projet la réponse ci-dessus fonctionne bien sauf pour la partie sidemenu quand je vais à la page sidemenu je ne suis pas en mesure de naviguer vers l'arrière je reçois le nom de composant comme page d'accueil même si je suis dans une autre page je vais à une page du menu latéral je ne vois pas les onglets est ce quelque chose qui cause une erreur toute aide comment naviguer vers la page d'accueil (tabspage) –

3

Comme par ionique 2 Documentation RC.4 de here:

Vous pouvez utiliser la méthode de registerBackButtonAction(callback, priority)Platform API pour enregistrer l'action sur la presse bouton retour.

L'événement du bouton de retour est déclenché lorsque l'utilisateur appuie sur le bouton de retour de la plate-forme native, également appelé bouton de retour "matériel". Cet événement est uniquement utilisé dans les applications Cordova s'exécutant sur les plates-formes Android et Windows. Cet événement n'est pas déclenché sur iOS car iOS ne dispose pas d'un bouton de retour matériel dans le même sens qu'un appareil Android ou Windows.

L'enregistrement d'une action de bouton de retour matériel et la définition d'une priorité permettent aux applications de contrôler quelle action doit être appelée lorsque le bouton de retour matériel est enfoncé. Cette méthode détermine laquelle des actions de bouton arrière enregistrées a la plus haute priorité et doit être appelée.

Paramètres:

  • rappel: fonction à appeler lorsque le bouton de retour est pressé, si cette action enregistrée est la plus haute priorité.
  • priorité: numéro permettant de définir la priorité pour cette action. Seule la priorité la plus élevée sera exécutée.Par défaut, 0

Retours: Fonction: Une fonction qui, lorsqu'elle est appelée, se désenregistrer l'action du bouton retour.

0

j'ai pu accomplir cela dans le cas où nous fixons simplement pages racine ...

import {Component, ViewChild, Injector} from '@angular/core'; 
import {Platform, MenuController, Nav, App, IonicApp, NavController} from 'ionic-angular'; 
import {StatusBar} from '@ionic-native/status-bar'; 
import {SplashScreen} from '@ionic-native/splash-screen'; 
import {InvitesPage} from "../pages/invites/invites"; 
import {RewardsPage} from "../pages/rewards/rewards"; 
import {ConnectionsPage} from "../pages/connections/connections"; 
import {MessagesPage} from "../pages/messages/messages"; 
import {ResourcesPage} from "../pages/resources/resources"; 
import {SignoutPage} from "../pages/signout/signout"; 
import {DashboardPage} from "../pages/dashboard/dashboard"; 
import {AccountPage} from "../pages/account/account"; 
import {HomePage} from "../pages/home/home"; 
import {TriviaPage} from "../pages/trivia/trivia"; 
import {Events} from "ionic-angular/util/events"; 


@Component({ 
    templateUrl: 'app.html' 
}) 
export class MyApp { 
    @ViewChild(Nav) nav: NavController; 
    // make HelloIonicPage the root (or first) page 

    public rootPage: any; //if logged in, go to dashboard. 
    public pages: Array<{title: string, component: any}>; 
    public user: any; 
    public routeHistory: Array<any>; 

    constructor(public platform: Platform, 
       public menu: MenuController, 
       public statusBar: StatusBar, 
       public splashScreen: SplashScreen, 
       private _app: App, 
       private _ionicApp: IonicApp, 
       private _menu: MenuController, 
       protected injector: Injector, 
       public _events: Events) { 

    this.initializeApp(); 

    // set our app's pages 
    this.pages = [ 
     {title: 'My Account', component: AccountPage}, 
     {title: 'Dashboard', component: DashboardPage}, 
     {title: 'Invites', component: InvitesPage}, 
     {title: 'Rewards', component: RewardsPage}, 
     {title: 'Connections', component: ConnectionsPage}, 
     {title: 'Messages', component: MessagesPage}, 
     {title: 'Resources', component: ResourcesPage}, 
     {title: 'Trivia', component: TriviaPage}, 
     {title: 'Sign Out', component: SignoutPage} 

    ]; 

    this.routeHistory = []; 
    this.user = {firstName: ''}; 

    } 

    initializeApp() { 

    this.platform.ready().then(() => { 

     this._setupBrowserBackButtonBehavior(); 

     let self = this; 
     if (sessionStorage.getItem('user')) { 
     this.user = JSON.parse(sessionStorage.getItem('user')); 
     self.rootPage = TriviaPage; 
     } else { 
     self.rootPage = HomePage; 
     } 

     this.routeHistory.push(self.rootPage); 
     // Okay, so the platform is ready and our plugins are available. 
     // Here you can do any higher level native things you might need. 
     this.statusBar.styleDefault(); 
     this.splashScreen.hide(); 
    }); 
    } 

    openPage(page) { 
    // close the menu when clicking a link from the menu 
    this.menu.close(); 
    // navigate to the new page if it is not the current page 
    this.nav.setRoot(page.component); 
    //store route history 
    this.routeHistory.push(page.component); 
    } 


    private _setupBrowserBackButtonBehavior() { 

    // Register browser back button action(s) 
    window.onpopstate = (evt) => { 

     // Close menu if open 
     if (this._menu.isOpen()) { 
     this._menu.close(); 
     return; 
     } 

     // Close any active modals or overlays 
     let activePortal = this._ionicApp._loadingPortal.getActive() || 
     this._ionicApp._modalPortal.getActive() || 
     this._ionicApp._toastPortal.getActive() || 
     this._ionicApp._overlayPortal.getActive(); 

     if (activePortal) { 
     activePortal.dismiss(); 
     return; 
     } 

     if (this.routeHistory.length > 1) { 
     this.routeHistory.pop(); 
     this.nav.setRoot(this.routeHistory[this.routeHistory.length - 1]); 
     } 


    }; 

    // Fake browser history on each view enter 
    this._app.viewDidEnter.subscribe((app) => { 
     if (this.routeHistory.length > 1) { 
     history.pushState(null, null, ""); 
     } 

    }); 

    } 
} 
4

ionique dernière version app.component.ts 3.xx fichier import { Platform, Nav, Config, ToastController} from 'ionic-angular';

constructor(public toastCtrl: ToastController,public platform: Platform) { 
platform.ready().then(() => { 
     //back button handle 
     //Registration of push in Android and Windows Phone 
     var lastTimeBackPress=0; 
     var timePeriodToExit=2000; 

    platform.registerBackButtonAction(() => { 
    // get current active page 
     let view = this.nav.getActive(); 
    if(view.component.name=="TabsPage"){ 
        //Double check to exit app     
        if(new Date().getTime() - lastTimeBackPress < timePeriodToExit){ 
         this.platform.exitApp(); //Exit from app 
        }else{ 
         let toast = this.toastCtrl.create({ 
          message: 'Press back again to exit App?', 
          duration: 3000, 
          position: 'bottom' 
          }); 
          toast.present();  
          lastTimeBackPress=new Date().getTime(); 
        } 
    }else{ 
     // go to previous page 
       this.nav.pop({}); 
    } 
    }); 

}); 

} 
0

J'ai trouvé le le plus facile, il suffit d'ajouter le code suivant dans app.component:

this.platform.registerBackButtonAction((event) => { 
    let activePortal = this.ionicApp._loadingPortal.getActive() || 
    this.ionicApp._modalPortal.getActive() || 
    this.ionicApp._toastPortal.getActive() || 
    this.ionicApp._overlayPortal.getActive(); 
    if(activePortal && activePortal.index === 0) { 
     /* closes modal */ 
     activePortal.dismiss(); 
    } else { 
     if(this.nav.getActive().name == 'Homepage') { // your homepage 
      this.platform.exitApp(); 
     } 
     else { 
      if(this.nav.canGoBack()) 
       this.nav.pop(); 
      this.nav.setRoot(Homepage); 
     } 
    } 
},101); 

Ca y est! Pas besoin d'ajouter du code supplémentaire sur chaque page!

3

J'ai utilisé des réponses d'ici et d'autres sources pour accomplir ce dont j'avais besoin. Je remarqué que lorsque vous construisez l'application pour la production (--prod) cette approche ne fonctionne pas, à cause de JS uglifying et en simplifiant:

this.nav.getActive().name == 'PageOne' 

À cause de cela, je l'utilise ensuite dans le « si » :

view.instance instanceof PageOne 

Ainsi, le code final ressemble à ceci:

this.platform.ready().then(() => { 

    //Back button handling 
    var lastTimeBackPress = 0; 
    var timePeriodToExit = 2000; 
    this.platform.registerBackButtonAction(() => { 
    // get current active page 
    let view = this.nav.getActive(); 
    if (view.instance instanceof PageOne) { 
     if (new Date().getTime() - lastTimeBackPress < timePeriodToExit) { 
      this.platform.exitApp(); //Exit from app 
     } else { 
     let toast = this.toastCtrl.create({ 
      message: 'Tap Back again to close the application.', 
      duration: 2000, 
      position: 'bottom', 
     }); 
     toast.present();  
     lastTimeBackPress = new Date().getTime(); 
     } 
    } else if (view.instance instanceof PageTwo || view.instance instanceof PageThree) { 
     this.openPage(this.pages[0]); 
    } else { 
     this.nav.pop({}); // go to previous page 
    } 
    }); 
}); 
0

la meilleure solution pratique après longue recherche.

il fonctionne à 100%, et testé dans le dispositif réel

this.Platform.registerBackButtonAction(() => { 
 
      // try to dismiss any popup or modal 
 
      console.log("Back button action called"); 
 

 
      let activePortal = this.ionicApp._loadingPortal.getActive() || 
 
      this.ionicApp._modalPortal.getActive() || 
 
      this.ionicApp._toastPortal.getActive() || 
 
      this.ionicApp._overlayPortal.getActive(); 
 

 
      if (activePortal) { 
 
      // ready = false; 
 
      activePortal.dismiss(); 
 
      activePortal.onDidDismiss(() => { }); 
 

 
      console.log("handled with portal"); 
 
      return; 
 
      } 
 

 
      // try to close the menue 
 

 
      if(this.MenuController.isOpen()){ 
 
      this.closeMenu(); 
 
      return; 
 
      } 
 
      else if(this.nav.canGoBack()){ 
 
      this.nav.pop(); 
 
      return; 
 
      }else{ 
 

 
      let activePage = this.nav.getActive().instance; 
 

 
      let whitelistPages = [LoginPage, HomePage]; 
 

 
      // if current page is not in whitelistPage 
 
      // then back to home or login page first 
 
      if (whitelistPages.indexOf(activePage.constructor) < 0) { 
 
       this.nav.setRoot(this.userLoggedIn ? HomePage : LoginPage); 
 

 
       return; 
 
      }else if(whitelistPages.indexOf(activePage.constructor) > 0){ 
 
       this.AppUtilities.showConfirm("Exit","Are you want to exist the app ? ").subscribe(
 
       ()=>{ 
 
        this.Platform.exitApp(); 
 
       }, 
 
       ()=>{} 
 
      ) 
 
      }else{ 
 
       console.error('cannot handel back button') 
 
      } 
 

 

 
      } 
 

 
     });

0

J'ai une approche légère Comparer avec @amr abdulaziz. Im en utilisant le setTimeout pour contrôler le retour ou quitter. Espérons que cela donnerait une autre option pour implémenter le bouton de retour.

initBackButtonBehaviour() { 
 
    this.platform.registerBackButtonAction(() => { 
 
     console.log("Back button pressed"); 
 
     if (this.readyToExit) { 
 
     this.platform.exitApp(); 
 
     return; 
 
     } 
 

 
     let activePortal = this.ionicApp._loadingPortal.getActive() || 
 
     this.ionicApp._modalPortal.getActive() || 
 
     this.ionicApp._toastPortal.getActive() || 
 
     this.ionicApp._overlayPortal.getActive(); 
 

 
     if (activePortal) { 
 
     activePortal.dismiss(); 
 
     activePortal.onDidDismiss(() => { }); 
 

 
     return; // stop any further action after closing any pop up modal or overlay 
 
     } 
 

 
     if (this.menuCtrl.isOpen()) { 
 
     this.menuCtrl.close(); 
 
     return; // stop any further action after menu closed 
 
     } 
 
     else if (this.nav.canGoBack()) { 
 
     this.nav.pop(); 
 
     return; // stop any further action after navigation pop 
 
     } 
 
     else { 
 
     let activePage = this.nav.getActive().instance; 
 

 
     let whiteListPages = [HomePage]; 
 

 
     // if current page is not in whitelistPage 
 
     // then back to home or login page first 
 
     if (whiteListPages.indexOf(activePage.constructor) < 0) { 
 
      this.nav.setRoot(HomePage); 
 

 
      return; 
 
     } else if (whiteListPages.indexOf(activePage.constructor) >= 0) { 
 
      this.utils.showToast('Press back button again to exit', 1500); 
 

 
      this.readyToExit = true; 
 
      setTimeout(() => { 
 
      this.readyToExit = false; 
 
      }, 1500); 
 

 
     } else { 
 
      console.error('cannot handle back button'); 
 
     } 
 

 
     } 
 
    }, 101);