AngularJS中路由切换时如何在控制器加载前关闭所有UI Bootstrap模态框
解决UI-Router路由切换时在控制器初始化前关闭所有UI Bootstrap模态框
你的问题核心在于使用了Angular核心的$locationChangeStart事件,它的触发时机晚于UI-Router的控制器初始化,导致新控制器创建的模态框被误关闭。UI-Router本身提供了更早触发的路由事件,完全可以解决这个问题,而且不需要修改任何控制器代码。
方案1:针对UI-Router 0.x版本(旧版)
直接替换$locationChangeStart监听为UI-Router的$stateChangeStart事件,这个事件会在状态切换开始、目标控制器初始化之前触发:
app.run(function($rootScope, $uibModalStack) { // 移除原来的$locationChangeStart监听 // 替换为$stateChangeStart监听 $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) { $uibModalStack.dismissAll("location change dismiss all"); }); });
方案2:针对UI-Router 1.x及以上版本(新版)
新版UI-Router推荐使用$transitions服务来监听状态切换,onStart钩子同样会在控制器初始化前触发:
app.run(function($transitions, $uibModalStack) { $transitions.onStart({}, function() { $uibModalStack.dismissAll("location change dismiss all"); }); });
为什么这个方案有效?
- 原来的
$locationChangeStart是Angular框架层面的事件,它的触发时机是在UI-Router完成状态切换、目标控制器已经实例化并执行完初始化代码之后,所以会出现“新模态框刚创建就被关闭”的问题。 - 而UI-Router的
$stateChangeStart(或$transitions.onStart)是路由系统原生的事件,触发时机远早于控制器初始化,执行$uibModalStack.dismissAll之后,新控制器再创建模态框就不会被误触发的关闭操作影响了。
这个方案完全不需要修改任何控制器代码,只需要替换run块里的事件监听逻辑即可,比用$timeout的临时方案更可靠、更符合路由切换的逻辑流程。
内容的提问来源于stack exchange,提问作者Scar
相关产品推荐
相关产品推荐

