Ionic覆盖特定控制器的所有BACK按钮行为

Ric*_*ier 23 ionic-framework ionic

我希望能够覆盖导航栏上的BACK按钮和硬件按钮.

我希望这个覆盖是针对一个特定的控制器,而不是其他控制器.

  • 当用户移动到另一个屏幕时必须取消它

(使用离子v1.0.0铀 - 独角兽)


我的理由是我有一个项目清单.单击列表将打开一个详细信息页面,其中包含3个选项卡.每个选项卡共享同一个控制器.

但是,在任何这些选项卡上按BACK必须返回主列表.这就是它在本机设备上的工作方式,所以我希望它能够在我的混合应用程序上运行.


在线提供的许多解决方案似乎适用于较旧的beta版本,或者用于控制器之外的注册.

在控制器内部使用Android硬件按钮的常见解决方案是:

$ionicPlatform.registerBackButtonAction(function (event) {
  if($state.current.name=="home"){
    alert("button back");
  }
}, 100);
Run Code Online (Sandbox Code Playgroud)

然而,这似乎不适用于软导航栏按钮,它适用于所有控制器,而不仅仅是一个控制器.

Ric*_*ier 61

可以覆盖控制器中的两个按钮,而无需更改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);
};
Run Code Online (Sandbox Code Playgroud)

在您自己的控制器中覆盖它很简单.确保您传入$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();
};
Run Code Online (Sandbox Code Playgroud)

覆盖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 Code Online (Sandbox Code Playgroud)

更多细节在这里:


完整的解决方案需要以下内容:

  • 覆盖软导航栏BACK按钮
  • 覆盖Android硬BACK按钮
  • 范围将是一个控制器
  • 恢复默认行为

以下代码说明了如何完成此操作:

// 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();
});
Run Code Online (Sandbox Code Playgroud)

此问题已在Ionic论坛和问题页面上讨论过:

  • 这对我们来说非常有效.我们有嵌套的ui-views,我们希望后退按钮可以使用.我们最终采用这种方法并在子视图的父控制器中使用"window.history.back()"代替$ ionicGoBack().虽然离子没有跟踪浏览器的子视图历史堆栈. (2认同)

oal*_*cht 6

我接受了理查德的建议,并将其投入服务,使其更具可重用性.

控制器

angular.module('MainApp').controller('MyController', ['backButtonOverride'], function (backButtonOverride) {
    // override back button for this controller
    backButtonOverride.setup($scope, function() {
        console.log("custom back");
    });
}
Run Code Online (Sandbox Code Playgroud)

服务

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;
});
Run Code Online (Sandbox Code Playgroud)