2016-12-29 67 views
14

Jak mogę obsłużyć działanie przycisku Wstecz na Ionic 2?Jak obsługiwać przycisk Wstecz w systemie Ionic 2

Chcę wiedzieć, co robić w zależności od tego, która strona jest wyświetlana użytkownikowi.

Nie znalazłem dobrej odpowiedzi na to pytanie, ale po pewnym czasie wymyśliłem sobie, jak to zrobić. Podzielę się z wami wszystkimi.

Dzięki

+0

Dlaczego na ziemi odpowiedzi poniżej, aby to pytanie jest tak trudne i nie czuć się jak wdrożenie? :(Jaki byłby najprostszy i najprostszy sposób? –

Odpowiedz

22

Oto jak to zrobiłem:

W każdym elemencie strony, stworzyłem funkcję o nazwie backButtonAction(), który będzie wykonywał niestandardowego kodu dla każdej strony.

Kod:

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

A w app.component.ts użyłem metody platform.registerBackButtonAction zarejestrować wywołania zwrotnego, która będzie wywoływana za każdym razem przycisk wstecz kliknięciu. Wewnątrz sprawdzam, czy na bieżącej stronie istnieje funkcja backButtonAction i wywołuję ją, jeśli nie istnieje, po prostu przejdź do karty głównej/pierwszej.

Można to uprościć, jeśli nie trzeba wykonywać dostosowanych działań dla każdej strony. Możesz po prostu otworzyć lub zamknąć aplikację.

Zrobiłem to w ten sposób, ponieważ musiałem sprawdzić, czy modal był otwarty na tej konkretnej stronie.

Kod:

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

czy bieżąca strona jest pierwsza zakładka, zamyka aplikacji (jak określono w metodzie backButtonAction).

+0

let nav = app.getActiveNav(); ** jaka jest ta aplikacja ** –

+1

Jest to instancja składnika "App", importowana z 'ionic-angleular' –

+0

i używam zakładek i sidemenu w moim projekcie powyższa odpowiedź działa dobrze z wyjątkiem części sidemenu, kiedy wchodzę do strony formularza sidemenu Nie mogę nawigować do tyłu Otrzymuję nazwę komponentu jako stronę główną, nawet jeśli jestem na innej stronie, gdy przechodzę do jakiejś strony z bocznego menu nie widzę kart, to jest coś, co powoduje błąd w jakiejkolwiek pomocy, jak przejść do strony głównej (tabulator) –

3

Zgodnie Ionic 2 dokumentacji RC.4 z here:

Można użyć registerBackButtonAction(callback, priority) metoda Platform API zarejestrować akcję na tylnej naciśnięciu przycisku.

Zdarzenie przycisku Wstecz jest wyzwalane, gdy użytkownik naciśnie przycisk powrotu natywnej platformy, zwany również "powrotem sprzętowym". To wydarzenie jest używane tylko w aplikacjach Cordova działających na platformach Android i Windows. To wydarzenie nie jest uruchamiane w systemie iOS, ponieważ iOS nie jest wyposażony w przycisk powrotu sprzętu w tym samym znaczeniu, co urządzenie z systemem Android lub Windows.

Rejestrowanie działania wstecznego przycisku sprzętu i ustawianie priorytetu umożliwia aplikacjom kontrolowanie, które działanie powinno zostać wywołane po naciśnięciu przycisku powrotu sprzętu. Ta metoda decyduje, które z zarejestrowanych działań przycisku wstecz ma najwyższy priorytet i powinno zostać wywołane.

Parametry:

  • oddzwonienia: funkcja do wywołania kiedy przycisk jest wciśnięty z powrotem, jeśli to zastrzeżony akcja ma najwyższy priorytet.
  • priorytet: Numer, aby ustawić priorytet dla tej akcji. Zostanie wykonany tylko najwyższy priorytet.Domyślnie 0

Powroty: funkcyjne: funkcja, która, kiedy nazywa, będzie wyrejestrować tylną działanie przycisku. złożyć

0

udało mi się tego dokonać w przypadku, że jesteśmy po prostu ustawienie stron korzeniowych ...

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

Ionic Najnowsze wersja 3.xx app.component.ts 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

Znalazłem Najprostszy sposób, wystarczy dodać następujący kod w 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); 

To jest to! Nie trzeba dodawać dodatkowego kodu na każdej stronie!

3

Użyłem odpowiedzi tutaj i innych źródeł, aby osiągnąć to, czego potrzebowałem. Zauważyłem, że podczas budowania aplikacji dla produkcji (--prod) podejście to nie działa, ponieważ JS uglifying i uproszczenia:

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

z tego powodu, używam obok w „if” :

view.instance instanceof PageOne 

Więc ostateczny kod wygląda następująco:

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

rozwiązanie Dobrych praktyk po długich poszukiwaniach.

to działa w 100%, i przetestowane w rzeczywistym urządzeniu

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

mam lekką innego podejścia porównania z @amr Abdulaziz. Im przy użyciu setTimeout do sterowania powrotem lub wyjść. Mam nadzieję, że dałoby to inną opcję realizacji przycisku wstecz.

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

Powiązane problemy