我希望能够覆盖导航栏上的BACK按钮和硬件按钮。
我希望这个覆盖是针对一个特定的控制器,而不是其他控制器。
(使用离子v1.0.0铀 - 独角兽)
我的理由是我有一个项目清单。单击列表将打开一个详细信息页面,其中包含3个选项卡。每个选项卡共享同一个控制器。
但是,在任何这些选项卡上按BACK必须返回主列表。这就是它在原生设备上的工作方式,因此我希望它能够在我的混合应用程序上运行。
在线提供的许多解决方案似乎适用于较旧的测试版,或者用于控制器之外的注册。
在控制器内使用Android硬件按钮的常用解决方案是:
$ionicPlatform.registerBackButtonAction(function (event) {
if($state.current.name=="home"){
alert("button back");
}
}, 100);
然而,这似乎不适用于软导航栏按钮,它适用于所有控制器,而不仅仅是那个控制器。
答案 0 :(得分:61)
可以覆盖控制器中的两个按钮,而无需更改HTML代码。
总结:
$rootScope.$ionicGoBack()
$ionicPlatform.registerBackButtonAction()
以下详细说明。
覆盖软导航栏BACK按钮的解决方案来自于了解按下该按钮后Ionic的功能。
从Ionic docs for 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();
});
此处有更多详情:
完整的解决方案需要以下内容:
以下代码说明了如何做到这一点:
// 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论坛上讨论过。问题页面:
答案 1 :(得分:6)
我接受了理查德的建议并将其投入服务,以使其更具可重用性。
控制器
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;
});
答案 2 :(得分:2)
您是在谈论离线标题栏或离子导航栏上的后退按钮中的软导航?因为这很容易解决。只需为该模板创建自己的自定义标题栏。所以在那个状态模板上只使用这样的东西。
<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>
答案 3 :(得分:1)
以上覆盖$ rootScope的答案。$ ionicGoBack部分有效。
问题在于deregisterSoftBack的方式。我尝试了上面提到的$ scope。$ on('$ destroy',a_function)以及新的$ scope。$ on('$ ionicView.beforeLeave',a_function),都不起作用。
原因:新的控制器将在deregisterSoftBack之前输入,从而使取消注册失败。所以我稍微修改了解决方案以使其工作。
更改
var oldSoftBack = $rootScope.$ionicGoBack
到
$rootScope.oldSoftBack = $rootScope.$ionicGoBack
取消注册$ rootScope。$ on(“$ stateChangeStart”,your_function),代码为:
if ($rootScope.oldSoftBack) {
$rootScope.$ionicGoBack = $rootScope.oldSoftBack;
$rootScope.oldSoftBack = null;
}
答案 4 :(得分:0)
从@ 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');
});
答案 5 :(得分:0)
这是我的解决方案:)
将这部分代码放在你的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();
};
当用户点击导航后退按钮时,将自动调用此功能。
如果你想自己打电话给goBack,可以这样做:
$rootScope.$ionicGoBack();
如果您想要绕过自定义函数而声明它,请转到:
$ionicHistory.goBack();
您可以直接在每个控制器中为后退按钮指定不同的行为:)
答案 6 :(得分:0)
对于那些使用最新版本的电容器和离子的人来说,这是有效的:
import { Capacitor } from "@capacitor/core";
import { App as CapacitorApp } from "@capacitor/app";
const App: React.FC = () => {
const history = useHistory();
useEffect(() => {
if (Capacitor.isNativePlatform()) {
CapacitorApp.addListener("backButton", () => {
history.goBack();
});
}
});
return (
<IonApp>...