Подтвердить что ты не робот

Есть ли способ автоматически закрыть Angular UI Bootstrap modal при изменении маршрута?

У меня есть ссылки в шаблонах внутри модалов. Когда я нажимаю на них, текущая страница меняется, но наложение и модальное пребывание. Я мог бы добавить ng-click="dimiss()" к каждой ссылке во всех шаблонах в модалях, но есть ли лучший способ? Например. автоматически закрыть его при успешном изменении маршрута или добавить только один ng-click для каждого шаблона для обработки всех ссылок?

4b9b3361

Ответ 1

Если вы хотите, чтобы все открытые модалы были закрыты всякий раз, когда маршрут был успешно изменен, вы можете сделать это в одном центральном месте, прослушивая событие $routeChangeSuccess, например, в блоке запуска вашего приложения:

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

Здесь вы можете увидеть, что служба $uibModalStack получает инъекцию, по которой вы можете вызвать метод dismissAll - этот вызов закроет все текущие открытые модальности.

Итак, да, вы можете обрабатывать модалы, закрывающиеся централизованно, в одном месте, с одной строкой кода:-)

Ответ 2

Лучше всего увидеть, что всякий раз, когда всплывающее окно (модальное) открыто, на кнопке "Назад браузера" (или "Клавиатура назад" ) мы останавливаем изменение 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);
            }
        });
    }]);

Ответ 3

Я действительно не использую Angular UI Bootstrap, но, глядя на docs, похоже, что есть close() метод объекта $modalInstance.

Поэтому, взяв пример из 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();
    });
};

Надеюсь, что это поможет.

Ответ 4

Я решил эту проблему, выполнив что-то вроде этого:

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

Ответ 5

Я сохраняю эту логику в модальном контроллере. Вы можете прослушать $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();
  });

}]);

Ответ 6

проверьте наличие соответствующего условия маршрута в событии $stateChangeSuccess и затем глобально закройте открытые модальности начальной загрузки, используя следующий класс:

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

Если вы хотите скрыть любые другие модалы, такие как диалог угловых материалов ($mdDialog) и диалог сладких оповещений, используйте angular.element('.modal-dialog').hide(); & angular.element('.sweet-alert').hide();

Ответ 7

Добавление этого альтернативного ответа.

В зависимости от вашего проекта использование $uibModalStack.dismissAll() может вызвать сообщение об ошибке.

Как объяснил JB Nizet в этом ответе, это вызвано тем, что dismissAll() отклонил обещание, что привело к dismissAll() ", в отличие от обратного вызова "success", вызванного close().

Отказ от обещания может привести к нежелательной процедуре обработки ошибок.

Учитывая, что в $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() - @line 4349

Мне понадобилось время, чтобы найти его.