Подтвердить что ты не робот

Как обращаться с кнопкой возврата на Ionic 2

Как я могу обработать действие кнопки "Назад" на Ionic 2?

Я хочу знать, что делать, в зависимости от того, какая страница отображается пользователю.

Я не нашел хорошего ответа на этот вопрос, но через некоторое время я решил, что это способ сделать это. Я собираюсь поделиться со всеми вами.

Спасибо

4b9b3361

Ответ 1

Вот как я это сделал:

В каждом компоненте страницы я создал функцию с именем backButtonAction(), которая будет выполнять пользовательский код для каждой страницы.

код:

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

И в app.component.ts я использовал метод platform.registerBackButtonAction для регистрации обратного вызова, который будет вызываться каждый раз при нажатии кнопки "Назад". Внутри я проверяю, существует ли функция backButtonAction на текущей странице и вызывает ее, если она не существует, просто перейдите на вкладку main/first.

Можно было бы упростить это, если им не нужно было выполнять индивидуальные действия для каждой страницы. Вы можете просто выйти или выйти из приложения.

Я сделал это так, потому что мне нужно было проверить, был ли модад открыт на этой странице.

код:

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

если текущая страница является первой вкладкой, приложение закрывается (как определено в методе backButtonAction).

Ответ 2

Согласно документации Ionic 2 RC.4 от здесь:

Вы можете использовать registerBackButtonAction(callback, priority) метод Platform API для регистрации нажатия кнопки "Назад" .

Событие кнопки "Назад" запускается, когда пользователь нажимает кнопку возврата на родные платформы, также называемую "аппаратной" кнопкой возврата. Это событие используется только в приложениях Cordova, работающих на платформах Android и Windows. Это событие не запускается на iOS, так как iOS не поставляется с кнопкой возврата аппаратного обеспечения в том же смысле, что и устройство Android или Windows.

Регистрация действия кнопки "Назад" и настройка приоритета позволяют приложениям определять, какое действие следует вызывать при нажатии кнопки "Назад" . Этот метод определяет, какой из зарегистрированных действий кнопки обратной связи имеет наивысший приоритет и должен быть вызван.

Параметры:

  • callback: функция, вызываемая при нажатии кнопки "Назад" , если это зарегистрированное действие имеет наивысший приоритет.
  • приоритет: номер для установки приоритета для этого действия. Выполняется только самый высокий приоритет. По умолчанию 0

Возвращает: Функция. Функция, которая при вызове отменяет регистрацию действия кнопки "Назад" .

Ответ 3

Ионная Последняя версия 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({});
    }
  });

});

}

Ответ 4

Я использовал ответы отсюда и других источников, чтобы выполнить то, что мне нужно. Я заметил, что при создании приложения для производства (-prod) этот подход не работает, поскольку JS угадает и упрощает:

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

Из-за этого я использую следующий оператор "if":

view.instance instanceof PageOne

Итак, окончательный код выглядит следующим образом:

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

Ответ 5

Я смог выполнить это в том случае, если мы просто устанавливаем корневые страницы...

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

    });

  }
}

Ответ 6

Я нашел Самый простой способ, просто добавьте следующий код в 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);

Что это! Не нужно добавлять дополнительный код на каждую страницу!

Ответ 7

Лучшее решение после длительного поиска.

он работает на 100% и протестировал его в реальном устройстве

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


          }

        });

Ответ 8

У меня есть небольшой подход к сравнению с @amr abdulaziz. Я использую setTimeout для управления или возврата. Надеюсь, это даст другой вариант для реализации кнопки "Назад".

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