Как обращаться с кнопкой возврата на Ionic 2
Как я могу обработать действие кнопки "Назад" на Ionic 2?
Я хочу знать, что делать, в зависимости от того, какая страница отображается пользователю.
Я не нашел хорошего ответа на этот вопрос, но через некоторое время я решил, что это способ сделать это. Я собираюсь поделиться со всеми вами.
Спасибо
Ответы
Ответ 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);