How to handle back button on Ionic 2

2020-01-26 06:25发布

How can I handle the back button action on Ionic 2?

I want to be able to know what to do depending on which page is being shown to the user.

I didn't find a good answer to this question, but after a while I figured it out myself a way to do it. I'm gonna share with you all.

Thanks

12条回答
贼婆χ
2楼-- · 2020-01-26 06:48

In Ionic 3 Lazy Loading, I never felt the need of Handling back behavior of browser where as for platform.is('cordova') I have created following method which handles all back scenarios:

// If a view controller is loaded. Just dismiss it.
let nav = this.app.getActiveNav();
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();
    return;
}

// If a state is pushed: Pop it.
if (this.nav.canGoBack()) {
  this.nav.pop();
  return;
} else 
// Else If its a tabs page: 
if (this.nav.getActiveChildNav()) {     
    const tabs: Tabs = this.nav.getActiveChildNav();
    const currentTab = tabs.getActiveChildNavs()[0];
    // If any page is pushed inside the current tab: Pop it
    if(currentTab.canGoBack()) {
      currentTab.pop();
      return;
    }
    else 
    // If home tab is not selected then select it.
    if(tabs.getIndex(currentTab) !=0){
      tabs.select(0);
      return;
    }
}
else 
// If a menu is open: close it.
if (this.menu.isOpen()) {
  this.menu.close();
  return;
}




if (this.exitApp) {
  this.platform.exitApp();
  return;
}
this.exitApp = true;

const toast = this.toastCtrl.create({
  message: this.exitMessage || 'press again to exit',
  duration: 4000,
  position: 'bottom',
  cssClass: 'exit-toastr',
});
toast.present();
setTimeout(() => {
  this.exitApp = false;
}, 2000);
查看更多
虎瘦雄心在
3楼-- · 2020-01-26 06:51

As per Ionic 2 RC.4 documentation from here:

You can use registerBackButtonAction(callback, priority) method of Platform API to register the action on back button press.

The back button event is triggered when the user presses the native platform’s back button, also referred to as the “hardware” back button. This event is only used within Cordova apps running on Android and Windows platforms. This event is not fired on iOS since iOS doesn’t come with a hardware back button in the same sense an Android or Windows device does.

Registering a hardware back button action and setting a priority allows apps to control which action should be called when the hardware back button is pressed. This method decides which of the registered back button actions has the highest priority and should be called.

Parameters :

  • callback : Function to be called when the back button is pressed, if this registered action has the highest priority.
  • priority : Number to set the priority for this action. Only the highest priority will execute. Defaults to 0

Returns: Function : A function that, when called, will un-register the back button action.

查看更多
贪生不怕死
4楼-- · 2020-01-26 06:53

I have Researched Many Things for back button handle Finally I Found a Good Solution for ionic latest Version 3.xx

//Check Hardware Back Button Double Tap to Exit And Close Modal On Hardware Back
      let lastTimeBackPress = 0;
      let timePeriodToExit  = 2000;
      this.platform.registerBackButtonAction(() => {
          let activePortal = this.ionicApp._loadingPortal.getActive() || // Close If Any Loader Active
          this.ionicApp._modalPortal.getActive() ||  // Close If Any Modal Active
          this.ionicApp._overlayPortal.getActive(); // Close If Any Overlay Active
          if (activePortal) {
              activePortal.dismiss();
          }
          else if(this.nav.canGoBack()){
            this.nav.pop();
          }else{
              //Double check to exit app
              if (new Date().getTime() - lastTimeBackPress < timePeriodToExit) {
                  this.platform.exitApp(); //Exit from app
              } else {
                this.toast.create("Press back button again to exit");
                lastTimeBackPress = new Date().getTime();
              }
          }            
      });
查看更多
再贱就再见
5楼-- · 2020-01-26 06:54

Here's how I did it:

In every Page component, I created a function called backButtonAction(), which will execute custom code for every 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();
    }
}

And in the app.component.ts, I used the platform.registerBackButtonAction method to register a callback that will be called everytime the back button is clicked. Inside it I check if the function backButtonAction exists in the current page and call it, if it doesn't exists, just go to the main/first tab.

One could simplify this if they didn't need to perform customized actions for every page. You could just pop or exit the app.

I did it this way because I needed to check if the modal was open on this particular page.

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

if the current page is the first tab, the app closes (as defined in the backButtonAction method).

查看更多
【Aperson】
6楼-- · 2020-01-26 06:56

I used answers from here and other sources to accomplish what I needed. I noticed that when you build the application for production (--prod) this approach doesn't work, because of JS uglifying and simplifying:

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

Because of that, I use next in the "if" statement:

view.instance instanceof PageOne

So the final code looks like this:

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
    }
  });
});
查看更多
你好瞎i
7楼-- · 2020-01-26 06:59

I found the Easiest way, just add the following code in 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);

That's it! No need to add extra code on every page!

查看更多
登录 后发表回答