【发布时间】:2014-07-08 20:44:15
【问题描述】:
我在模态框内的模板中有链接。当我单击它们时,当前页面会更改,但覆盖和模式会保留。我可以将ng-click="dimiss()" 添加到模式中所有模板的每个链接中,但是有更好的方法吗?例如。是在路线更改成功时自动关闭它,还是在每个模板中只添加一个ng-click 来处理所有链接?
【问题讨论】:
标签: angularjs angular-ui angular-ui-bootstrap
我在模态框内的模板中有链接。当我单击它们时,当前页面会更改,但覆盖和模式会保留。我可以将ng-click="dimiss()" 添加到模式中所有模板的每个链接中,但是有更好的方法吗?例如。是在路线更改成功时自动关闭它,还是在每个模板中只添加一个ng-click 来处理所有链接?
【问题讨论】:
标签: angularjs angular-ui angular-ui-bootstrap
我实际上并没有使用 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();
});
};
希望对您有所帮助。
【讨论】:
如果您希望在成功更改路线时关闭所有打开的模式,您可以通过监听$routeChangeSuccess 事件在一个中心位置执行此操作,例如在应用程序的运行块中:
var myApp = angular.module('app', []).run(function($rootScope, $uibModalStack) {
$uibModalStack.dismissAll();
});
在这里您可以看到$uibModalStack 服务被注入,您可以在该服务上调用dismissAll 方法 - 此调用将关闭所有当前打开的模式。
所以,是的,您可以使用一行代码在一处集中处理模态关闭:-)
【讨论】:
Unknown provider: $uibModalStackProvider
uibModalStack 文档的链接吗?到处都找不到……
我通过这样做解决了这个问题:
$rootScope.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams){
$modalStack.dismissAll();
});
【讨论】:
更好的方法是查看每当弹出(模态)打开时,在浏览器后退按钮单击(或键盘后退)时,我们停止 URL 更改并关闭弹出窗口。这有助于在我的项目中获得更好的用户体验。
浏览器返回按钮在没有打开Modal的情况下正常工作。
使用:
$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);
}
});
}]);
【讨论】:
我将这个逻辑保存在模态控制器中。您可以收听$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();
});
}]);
【讨论】:
在事件$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();
【讨论】:
添加这个替代答案。
根据您的项目,使用$uibModalStack.dismissAll() 可能会触发错误消息。
正如JB Nizet 在this 答案中所解释的,这是由dismissAll() 拒绝承诺引起的,导致“失败”回调,而不是由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
我花了一段时间才找到它。
【讨论】: