wake-up-neo.com

So behandeln Sie die Zurück-Taste an Ionic 2

Wie kann ich mit der Rücktastenaktion auf Ionic 2 umgehen?

Ich möchte wissen können, was zu tun ist, je nachdem, welche Seite dem Benutzer angezeigt wird.

Ich habe keine gute Antwort auf diese Frage gefunden, aber nach einer Weile habe ich selbst herausgefunden, wie ich es schaffen kann. Ich werde mit euch allen teilen.

Vielen Dank

15

So habe ich es gemacht:

In jeder Seitenkomponente habe ich eine Funktion mit dem Namen backButtonAction() erstellt, die für jede Seite benutzerdefinierten Code ausführt.

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

In app.component.ts habe ich die platform.registerBackButtonAction-Methode verwendet, um einen Rückruf zu registrieren, der jedes Mal aufgerufen wird, wenn der Zurück-Button angeklickt wird. Darin überprüfe ich, ob die Funktion backButtonAction auf der aktuellen Seite vorhanden ist, und rufe sie an.

Man könnte dies vereinfachen, wenn sie nicht für jede Seite angepasste Aktionen ausführen müssten. Sie können die App einfach öffnen oder beenden.

Ich habe es so gemacht, weil ich überprüfen musste, ob das Modal auf dieser bestimmten Seite geöffnet war.

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

wenn die aktuelle Seite die erste Registerkarte ist, wird die App geschlossen (wie in der backButtonAction-Methode definiert).

29

Ionic Neueste Version 3.xx app.component.ts-Datei 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({});
    }
  });

});

}
7
Mohamed Arshath

Ich habe Antworten von hier und aus anderen Quellen verwendet, um das zu erreichen, was ich brauchte ... Ich habe festgestellt, dass diese Methode beim Erstellen der Anwendung für die Produktion (--prod) aufgrund der JS-Vereinfachung und Vereinfachung nicht funktioniert:

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

Aus diesem Grund verwende ich next in der "if" -Anweisung:

view.instance instanceof PageOne

Der endgültige Code sieht also so aus:

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

Laut Ionic 2 RC.4 Dokumentation von hier :

Sie können die registerBackButtonAction(callback, priority)-Methode der Platform-API verwenden, um die Aktion beim Drücken der Zurück-Taste zu registrieren.

Das Back-Button-Ereignis wird ausgelöst, wenn der Benutzer den Back-Button der nativen Plattform drückt, der auch als „Hardware-Back-Button“ bezeichnet wird. Dieses Ereignis wird nur in Cordova-Apps verwendet, die auf Android- und Windows-Plattformen ausgeführt werden. Dieses Ereignis wird nicht unter iOS ausgelöst, da iOS nicht mit einer Zurück-Schaltfläche für die Hardware ausgestattet ist, wie dies bei einem Android- oder Windows-Gerät der Fall ist.

Durch das Registrieren einer Hardware-Zurücktastenaktion und das Festlegen einer Priorität können Apps steuern, welche Aktion aufgerufen werden soll, wenn die Hardware-Zurücktaste gedrückt wird. Diese Methode entscheidet, welche der registrierten Aktionen für die Zurückschaltfläche die höchste Priorität hat und aufgerufen werden sollte.

Parameter:

  • callback: Funktion, die aufgerufen wird, wenn die Zurück-Taste gedrückt wird, wenn diese registrierte Aktion die höchste Priorität hat.
  • Priorität: Nummer, um die Priorität für diese Aktion festzulegen. Nur die höchste Priorität wird ausgeführt. Standardeinstellung ist 0

Rückgabe: Funktion: Eine Funktion, die die Rücktastenaktion aufhebt, wenn sie aufgerufen wird.

3
Prerak Tiwari

In Ionic 3 Lazy Loading habe ich nie das Bedürfnis nach Rückhand-Verhalten des Browsers gefühlt, während für platform.is ('cordova') folgende Methode erstellt wurde, die alle Rückszenarien behandelt: 

// 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);
0
Arslan Ali

Eigentlich funktioniert ionViewWillLeave in meinem Fall besser.

 enter image description here

Hier sind die offiziellen Dokumente über Navigation im Lebenszyklus

0
Alexey Strakh

Ich habe den einfachsten Weg gefunden , fügen Sie einfach folgenden Code in app.component hinzu:

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

Das ist es!Keine Notwendigkeit, zusätzlichen Code auf jeder Seite hinzuzufügen!

0
Tushar Walzade

Im Vergleich zu @amr abdulaziz habe ich einen etwas anderen Ansatz. Ich benutze den setTimeout, um zurück zu steuern oder zu beenden. Ich hoffe, dies würde eine weitere Option für die Implementierung der Zurück-Taste geben.

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

0
Kimman wky

Best Practice Lösung nach langer Suche.

es funktioniert 100% und hat es in einem echten Gerät getestet 

   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
Amr Ibrahim

Ich habe viele Dinge für den hinteren Tastengriff recherchiert. Schließlich habe ich eine gute Lösung für die neueste Version 3.xx von ionic gefunden 

//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();
              }
          }            
      });
0
Mohamed Arshath

sie können diese Funktionen ausprobieren:

registerBackButton() {
        this.platform.registerBackButtonAction(() => {
            if (this.menu.isOpen()) {
                console.log("Menu is open!", "loggedInMenu");
                this.menu.close();
                console.log("this.menu.isOpen(): " + JSON.stringify(this.menu.isOpen()));
                return;
            }
            console.log("Checking for other pages");

            let checkHomePage = true;
            let max = Globals.navCtrls.length;
            for (let i = 0; i < Globals.navCtrls.length; i++) {
                let n = Globals.navCtrls[i];
                if (n) {
                    if (n.canGoBack()) {
                        console.log("Breaking the loop i: " + JSON.stringify(i));
                        let navParams = n.getActive().getNavParams();
                        if (navParams) {
                            console.log("navParams exists");
                            let resolve = navParams.get("resolve");
                            if (resolve) {
                                n.pop().then(() => resolve({}));
                            } else {
                                n.pop();
                            }
                        } else {
                            n.pop();
                        }
                        checkHomePage = false;
                        return;
                    }
                } else console.log("n was null!");
            }

            if (this.nav.getActive().instance instanceof TabsPage && !this.nav.canGoBack()) {
                let popPageVal = this.backbuttonService.popPage();
                console.log("popPageVal: " + JSON.stringify(popPageVal));
                if (popPageVal >= 0) {
                    console.log("Switching the tab to: ", popPageVal);
                    this.switchTab(popPageVal);
                } else {
                    console.log("Last page is HomePage");

                    if (this.alert) {
                        this.alert.dismiss();
                        this.alert = null;
                    } else {
                        this.showAlert();
                    }
                }
            } else {
                console.log("Last page is not HomePage");
                if (this.nav.canGoBack()) {
                    console.log("We can go back!");
                    this.nav.pop();
                }
            }
        });
    }

    showAlert() {
        this.alert = this.alertController.create({
            title: "Exit?",
            message: "Are you sure you want to exit?",
            buttons: [
                {
                    text: "Cancel",
                    role: "cancel",
                    handler: () => {
                        this.alert = null;
                    }
                },
                {
                    text: "Exit",
                    handler: () => {
                        this.platform.exitApp();
                    }
                }
            ]
        });
        this.alert.present();
    }

    switchTab(tabIndex) {
        if (Globals.tabs && tabIndex >= 0) {
            console.log("Switch condition met");
            Globals.tabIndex = tabIndex;
            Globals.tabs.select(tabIndex);
            Globals.tabs.selectedIndex = tabIndex;
        }
    }

Ich hoffe es klappt mit dir.

0
Amr AbdelRahman

Dies konnte ich erreichen, wenn wir einfach Stammseiten setzen ...

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

    });

  }
}
0
Judson Terrell