web-dev-qa-db-ja.com

Ionic特定のコントローラーのすべての[戻る]ボタンの動作をオーバーライドする

ナビゲーションバーの[戻る]ボタンとハードウェアボタンをオーバーライドできるようにしたい。

このオーバーライドを特定の1つのコントローラー用にしたいのですが、残りのコントローラー用ではありません。

  • ユーザーが別の画面に移動したときにキャンセルする必要があります

(ionic v1.0.0ウランユニコーンを使用)


私の理由は、アイテムのリストがあることです。リストをクリックすると、3つのタブがある詳細ページが開きます。各タブは同じコントローラーを共有します。

ただし、これらのタブのいずれかで[戻る]を押すと、メインリストに戻る必要があります。これがネイティブデバイスでの動作方法であるため、ハイブリッドアプリでの動作を希望します。


オンラインで提供される多くのソリューションは、古いベータ版用、またはコントローラーの外部での登録用のようです。

コントローラ内のAndroidハードウェアボタンを操作するための一般的なソリューションは次のとおりです。

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

ただし、これはソフトナビゲーションバーのボタンでは機能しないようで、1つだけでなくすべてのコントローラーで機能します。

22

HTMLコードを変更せずに、コントローラーの両方のボタンをオーバーライドすることができます

要約すると:

  • ソフトナビゲーションバーボタン-$rootScope.$ionicGoBack()をオーバーライドします
  • ハードAndroidボタン-$ionicPlatform.registerBackButtonAction()を使用

以下の詳細な説明。


ソフトナビゲーションバーの[戻る]ボタンをオーバーライドするの解決策は、そのボタンが押されたときにIonicが何をするかを理解することです。

_ion-nav-back-button_のIonicドキュメント から、次のことがすでにわかっています。

ボタンはクリック/タップで自動的に$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ボタンをオーバーライドするためのソリューションは、1つのコントローラーのみに対して、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();
});
_

詳細はこちら:


完全なソリューションには次のものが必要です。

  • ソフトナビゲーションバーの[戻る]ボタンを無効にする
  • オーバーライド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();
});
_

この問題は、Ionicフォーラムと問題のページで議論されています。

61

私はリチャードの提案を取り入れて、サービスを再利用可能にするサービスに入れました。

コントローラー

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

ion-header-barまたはion-nav-barの戻るボタンのようなソフトナビゲーションについて話していますか?原因は簡単に修正できます。そのテンプレート用に独自のカスタムヘッダーバーを作成するだけです。そのため、その状態テンプレートではこのようなものを使用します。

<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>
2
Jess Patton

$ rootScope。$ ionicGoBackをオーバーライドする上記の答えは部分的に機能します。

問題はderegisterSoftBackの方法にあります。上記の$ scope。$ on( '$ destroy'、a_function)と新しい$ scope。$ on( '$ ionicView.beforeLeave'、a_function)も試しましたが、どちらも動作しません。

その理由:deregisterSoftBackの前に新しいコントローラーが入力されるため、登録解除は失敗します。そこで、ソリューションを少し修正して、機能するようにしました。

  1. 変更

    var oldSoftBack = $rootScope.$ionicGoBack
    

    $rootScope.oldSoftBack = $rootScope.$ionicGoBack
    
  2. $ rootScope。$ on( "$ stateChangeStart"、your_function)で登録解除すると、コードは次のようになります。

    if ($rootScope.oldSoftBack) {
        $rootScope.$ionicGoBack = $rootScope.oldSoftBack;
        $rootScope.oldSoftBack = null;
    }
    
1
raven.zuo

これは私の解決策です:)

コードのこの部分を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;
    });

これで、コントローラーでカスタムゴーバック関数を作成できるようになりました。

$scope.customGoBack = function() {
   console.log( "customGoBack" );
   $scope.customGoBack.super();
};

ユーザーがnav-back-buttonをタップすると、この関数が自動的に呼び出されます。

自分でgoBackを呼び出す場合は、次の方法で実行できます。

$rootScope.$ionicGoBack();

宣言されているのにカスタム関数をバイパスしたい場合、ここに行きます:

$ionicHistory.goBack();

各コントローラの戻るボタンに異なる動作を直接割り当てることができます:)

0
mopi

@ 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');
    });
0
johnw86