Ионное изменение поведения кнопки BACK для конкретного контроллера
Я хочу иметь возможность переопределить кнопку BACK на панели навигации и кнопку аппаратного обеспечения.
Я хочу, чтобы это переопределение было для одного конкретного контроллера, но не для остальных контроллеров.
- он должен быть отменен, когда пользователь переместится на другой экран
(с использованием ионного v1.0.0 урана-единорога)
Моя причина в том, что у меня есть список предметов. При нажатии на список открывается страница с 3 вкладками. Каждая вкладка имеет один и тот же контроллер.
Однако нажатие BACK на любом из этих вкладок должно вернуться к основному списку. Вот как это работает на собственных устройствах, так что я хотел бы, чтобы он работал над моим гибридным приложением.
Многие решения, предоставляемые в Интернете, похоже, для старых бета-версий или для регистрации вне контроллеров.
Общее решение для работы с аппаратной кнопкой Android в контроллере:
$ionicPlatform.registerBackButtonAction(function (event) {
if($state.current.name=="home"){
alert("button back");
}
}, 100);
Однако, похоже, это не работает на кнопке мягкой навигационной панели, и она работает на всех контроллерах, а не только на одном.
Ответы
Ответ 1
Можно переопределить обе кнопки в вашем контроллере, без каких-либо изменений HTML-кода.
Подводя итог:
- Кнопка мягкой навигационной панели - переопределение
$rootScope.$ionicGoBack()
- Жесткая Android-кнопка - используйте
$ionicPlatform.registerBackButtonAction()
Подробные пояснения ниже.
Решение для переопределения мягкой навигационной панели Кнопка BACK происходит от понимания того, что делает Ionic при нажатии этой кнопки.
Из Ionic docs для ion-nav-back-button
мы уже знаем, что:
кнопка автоматически устанавливается на $ionicGoBack()
при щелчке/нажатии.
Поиск исходного кода в файле ionic.bundle.js показывает, как это объявлено:
$rootScope.$ionicGoBack = function(backCount) {
$ionicHistory.goBack(backCount);
};
Переопределение этого в вашем собственном контроллере просто. Убедитесь, что вы передали $rootScope
в контроллер и просто изменили приведенный выше код. Это хорошая идея, чтобы захватить указатель на исходную функцию, чтобы вы могли восстановить ее, если это необходимо, или вызвать ее, когда закончите с вашей пользовательской обработкой.
// grab pointer to original function
var oldSoftBack = $rootScope.$ionicGoBack;
// override default behaviour
$rootScope.$ionicGoBack = function() {
// do something interesting here
// uncomment below line to call old function when finished
// oldSoftBack();
};
Решение для переопределения кнопки Android BACK, только для одного контроллера, исходит из возвращаемого значения функции registerBackButtonAction()
, которая ведет к дерегистрации переопределения.
Вызовите этот метод дерегистрации в обработчике $scope.$on('$destroy'...
.
var doCustomBack= function() {
// do something interesting here
};
// registerBackButtonAction() returns a function which can be used to deregister it
var deregisterHardBack= $ionicPlatform.registerBackButtonAction(
doCustomBack, 101
);
$scope.$on('$destroy', function() {
deregisterHardBack();
});
Подробнее здесь:
Для полного решения потребуется следующее:
- переопределить мягкую навигационную панель Кнопка BACK
- переопределить кнопку жесткого диска Android
- scope будет единственным контроллером
- поведение по умолчанию восстановлено
Следующий код иллюстрирует, как это можно сделать:
// run this function when either hard or soft back button is pressed
var doCustomBack = function() {
console.log("custom BACK");
};
// override soft back
// framework calls $rootScope.$ionicGoBack when soft back button is pressed
var oldSoftBack = $rootScope.$ionicGoBack;
$rootScope.$ionicGoBack = function() {
doCustomBack();
};
var deregisterSoftBack = function() {
$rootScope.$ionicGoBack = oldSoftBack;
};
// override hard back
// registerBackButtonAction() returns a function which can be used to deregister it
var deregisterHardBack = $ionicPlatform.registerBackButtonAction(
doCustomBack, 101
);
// cancel custom back behaviour
$scope.$on('$destroy', function() {
deregisterHardBack();
deregisterSoftBack();
});
Эта проблема обсуждалась на форумах Ionic и выпускает страницы:
Ответ 2
Я взял предложение Ричарда и включил его в сервис, чтобы сделать его более многоразовым.
Контроллер
angular.module('MainApp').controller('MyController', ['backButtonOverride'], function (backButtonOverride) {
// override back button for this controller
backButtonOverride.setup($scope, function() {
console.log("custom back");
});
}
Служба
angular.module('MainApp.services', []).factory('backButtonOverride', function ($rootScope, $ionicPlatform) {
var results = {};
function _setup($scope, customBackFunction) {
// override soft back
// framework calls $rootScope.$ionicGoBack when soft back button is pressed
var oldSoftBack = $rootScope.$ionicGoBack;
$rootScope.$ionicGoBack = function() {
customBackFunction();
};
var deregisterSoftBack = function() {
$rootScope.$ionicGoBack = oldSoftBack;
};
// override hard back
// registerBackButtonAction() returns a function which can be used to deregister it
var deregisterHardBack = $ionicPlatform.registerBackButtonAction(
customBackFunction, 101
);
// cancel custom back behaviour
$scope.$on('$destroy', function() {
deregisterHardBack();
deregisterSoftBack();
});
}
results.setup = _setup;
return results;
});
Ответ 3
Вы говорите о мягкой навигации, как в задней кнопке на ионной панели заголовка или ион-навигационной панели? потому что это легко исправить. Просто создайте собственную панель заголовков для этого шаблона. так что на этом шаблоне состояния просто используйте что-то вроде этого.
<div class="bar bar-header bar-positive">
<button ng-click="someCustomFunction()" class="button button-clear button-light icon-left ion-chevron-left">Go Back</button>
</div>
Ответ 4
Вышеупомянутый ответ на переопределение $rootScope. $ionicGoBack частично работает.
Проблема заключается в способе отмены регистрацииSoftBack. Я попробовал вышеупомянутую $scope. $On ('$ destroy', a_function), а также новую $scope. $On ('$ ionicView.beforeLeave', a_function) не работает.
Причина этого: новый контроллер будет введен до того, как будет отменен регистраторSoftBack, чтобы отменить регистратор. Поэтому я немного изменил решение, чтобы оно работало.
-
измените
var oldSoftBack = $rootScope.$ionicGoBack
to
$rootScope.oldSoftBack = $rootScope.$ionicGoBack
-
deregister в $rootScope. $on ( "$ stateChangeStart", your_function), код:
if ($rootScope.oldSoftBack) {
$rootScope.$ionicGoBack = $rootScope.oldSoftBack;
$rootScope.oldSoftBack = null;
}
Ответ 5
Взял обратную связь от @raven.zuo и внес некоторые исправления, чтобы отменить регистрацию события изменения состояния.
(function () {
'use strict';
angular
.module('appName')
.service('customBackButtonService', customBackButtonService);
customBackButtonService.$inject = ['$rootScope', '$ionicPlatform'];
function customBackButtonService($rootScope, $ionicPlatform) {
var service = {
setup: setup
};
return service;
////////////////
function setup(customBackFunction) {
// override soft back
// framework calls $rootScope.$ionicGoBack when soft back button is pressed
$rootScope.oldSoftBack = $rootScope.$ionicGoBack;
$rootScope.$ionicGoBack = function () {
customBackFunction();
};
var deregisterSoftBack = function () {
$rootScope.$ionicGoBack = $rootScope.oldSoftBack;
};
// override hard back
// registerBackButtonAction() returns a function which can be used to deregister it
var deregisterHardBack = $ionicPlatform.registerBackButtonAction(
customBackFunction, 101
);
// cancel custom back behaviour
var backStateChangeWatcher = $rootScope.$on('$stateChangeStart', function () {
if($rootScope.oldSoftBack){
deregisterHardBack();
deregisterSoftBack();
// Un-register watcher
backStateChangeWatcher();
}
});
}
}
})();
//Called via:
customBackButtonService.setup(function () {
console.log('custom back');
});
Ответ 6
это мое решение:)
Поместите эту часть кода в свою функцию запуска app.js:
//** Go Back interception function ------------------------------------------
var currentScope;
var defaultGoBack = $rootScope.$ionicGoBack;
$rootScope.$ionicGoBack = function() {
if ( angular.isFunction( currentScope.customGoBack ) ) {
//assign default go back function to as a "super" function ^^
currentScope.customGoBack.super = defaultGoBack;
//if there is a custom back function, execute-it
currentScope.customGoBack();
} else {
//else, execute default go back
defaultGoBack();
}
};
//Store targetScope to global each time the view is changing
$rootScope.$on( '$ionicView.beforeEnter', function( event ) {
currentScope = event.targetScope;
});
Теперь вы можете создать пользовательскую функцию goback в контроллерах:
$scope.customGoBack = function() {
console.log( "customGoBack" );
$scope.customGoBack.super();
};
Эта функция будет автоматически вызываться, когда пользователь нажимает кнопку nav-back-button.
Если вы хотите позвонить goBack самостоятельно, вы можете сделать это следующим образом:
$rootScope.$ionicGoBack();
Если вы хотите обойти пользовательскую функцию, тогда как она объявлена, вы здесь:
$ionicHistory.goBack();
Вы можете назначить другое поведение для кнопки "Назад" непосредственно в каждом контроллере:)