web-dev-qa-db-ja.com

Angular UI Bootstrap=ルートが変更されたときにモーダルを自動的に閉じる方法はありますか?

モーダル内のテンプレートにリンクがあります。それらをクリックすると、現在のページが変更されますが、オーバーレイとモーダルは残ります。モーダルのすべてのテンプレートのすべてのリンクにng-click="dimiss()"を追加できますが、より良い方法はありますか?例えば。ルートの変更が成功したときに自動的に閉じるか、ng-clickテンプレートごとにすべてのリンクを処理しますか?

52
szimek

ルートが正常に変更されるたびに、開いているすべてのモーダルを閉じたい場合は、$routeChangeSuccessイベント、たとえば、アプリの実行ブロック内:

var myApp = angular.module('app', []).run(function($rootScope, $uibModalStack) {
  $uibModalStack.dismissAll();
}); 

ここで、$uibModalStackサービスが挿入され、dismissAllメソッドを呼び出すことができます-この呼び出しは、現在開いているすべてのモーダルを閉じます。

したがって、はい、1行のコードで1か所で集中的に閉じるモーダルを処理できます:-)

100

より良い方法は、ポップアップ(モーダル)が開いているときはいつでも、ブラウザーの戻るボタンのクリック(またはキーボードの戻る)で、URLの変更を停止してポップアップを閉じることです。これは、私のプロジェクトのユーザーエクスペリエンスを向上させるために機能します。

モーダルが開かれていない場合、ブラウザの戻るボタンは正常に機能します。

つかいます:

$uibModalStack.dismiss(openedModal.key);

または

$uibModalStack.dismissAll;

サンプルコード:

.run(['$rootScope', '$uibModalStack',
    function ($rootScope,  $uibModalStack) {       
        // close the opened modal on location change.
        $rootScope.$on('$locationChangeStart', function ($event) {
            var openedModal = $uibModalStack.getTop();
            if (openedModal) {
                if (!!$event.preventDefault) {
                    $event.preventDefault();
                }
                if (!!$event.stopPropagation) {
                    $event.stopPropagation();
                }
                $uibModalStack.dismiss(openedModal.key);
            }
        });
    }]);
14
GamaSharma

実際にはAngular UI Bootstrapを使用していませんが、 docs を見ると、$modalInstanceオブジェクトにclose()メソッドがあるように見えます。

docs の例を使用すると、これは機能するはずです。

var ModalInstanceCtrl = function ($scope, $modalInstance, items) {
    $scope.items = items;
    $scope.selected = {
        item: $scope.items[0]
    };
    $scope.ok = function () {
        $modalInstance.close($scope.selected.item);
    };
    $scope.cancel = function () {
        $modalInstance.dismiss('cancel');
    };

    // this will listen for route changes and call the callback
    $scope.$on('$routeChangeStart', function(){
        $modalInstance.close();
    });
};

お役に立てば幸いです。

3
tennisgent

このようなことをして、この問題を解決しました。

$rootScope.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams){
$modalStack.dismissAll();
});
2
kiran.gilvaz

このロジックをモーダルコントローラーに保持しています。 $locationChangeStartイベントと閉じるモーダルがあります。特に、$rootScope

angular.module('MainApp').controller('ModalCtrl',['$scope','$uibModalInstance',
function ($scope, $uibModalInstance) {

  var dismissModalListener = $scope.$on('$locationChangeStart', function () {
    $uibModalInstance.close();
  });

  $scope.$on('$destroy', function() {
    dismissModalListener();
  });

}]);
1

これに別の答えを追加します。

プロジェクトによっては、$uibModalStack.dismissAll()を使用するとエラーメッセージが表示される場合があります。

JB Nizet in this answerで説明されているように、dismissAll()がプロミスを拒否し、 'ではなく'失敗 'コールバックが発生するclose()によってトリガーされるsuccess 'コールバック。

約束の拒否は、望ましくないエラー処理手順を引き起こす可能性があります。

_$uibModalStack_にcloseAll()がない場合、これを使用しました:

_    var modal = $uibModalStack.getTop();
    while (modal && this.close(modal.key)) {
      modal = this.getTop();
    }
_

これは$uibModalStack.dismissAll()と同じ動作ですが、.close()の代わりに.dismiss()を利用します。

_$uibModalStack_のパブリックメソッドを説明するドキュメントが見つかりませんでした。したがって、誰かが_$uibModalStack_で利用可能な他のメソッドの使用/参照に興味がある場合に備えてください。

おそらく_\node-modules\angular-ui-boostrap\dist\ui-boostrap-tpls.js_にあり、dismissAll()は4349行目です。

それを見つけるのにしばらくかかった。

0
mrOak

イベント$stateChangeSuccessでそれぞれのルート条件を確認してから、次のようなクラスを使用して、開いているbootstrapモーダルをグローバルに閉じます。

$rootScope.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams){
//hide any open bootstrap modals
  angular.element('.inmodal').hide();
});

angular material dialog($mdDialog)&sweet alert dialog's use angular.element('.modal-dialog').hide();angular.element('.sweet-alert').hide();などの他のモーダルを非表示にする場合

0
Sri7