AngularJS ui-router父状态resolve函数子路由切换时未触发问题咨询
问题原因分析
这是因为ui-router中父状态的resolve只会在该状态首次被激活时执行一次。你的app是抽象父状态,当第一次进入app.home时,app状态会被初始化,此时resolve里的函数会运行;但当你在app.home和app.profile之间切换时,app状态始终处于激活状态(没有被销毁或重新加载),所以resolve中的逻辑不会再次触发。
解决方案
根据你的需求,有几种可行的实现方式:
1. 全局监听路由切换事件
可以在应用的run块中监听$stateChangeSuccess事件,每次路由切换完成后执行你的函数:
angular.module('yourApp').run(function($rootScope) { $rootScope.$on('$stateChangeSuccess', function(event, toState) { // 仅当切换到app下的子状态时执行 if (toState.name.indexOf('app.') === 0) { console.log('test'); // 这里放入你需要触发的逻辑 } }); });
如果你的ui-router版本是1.0+,推荐使用更现代的$transitions服务:
angular.module('yourApp').run(function($transitions) { $transitions.onSuccess({}, function(trans) { var toState = trans.to(); if (toState.name.indexOf('app.') === 0) { console.log('test'); } }); });
2. 在父状态控制器中监听事件
如果希望逻辑和父状态绑定,可以给app状态添加控制器,在控制器内部监听路由切换事件,记得在控制器销毁时移除监听避免内存泄漏:
首先修改路由配置,给app状态添加控制器:
.state('app', { url: '/app', abstract: true, templateUrl: 'pages/menu.html', controller: 'MenuController' // 添加这一行 })
然后定义控制器:
angular.module('yourApp').controller('MenuController', function($rootScope, $scope) { // 注册路由切换监听 var stateChangeHandler = $rootScope.$on('$stateChangeSuccess', function(event, toState) { if (toState.name.indexOf('app.') === 0) { console.log('test'); } }); // 控制器销毁时移除监听 $scope.$on('$destroy', function() { stateChangeHandler(); }); });
3. 子状态共享resolve依赖(不推荐)
如果你想通过resolve的方式触发,需要让每个子状态都依赖一个会每次执行的resolve,但这种方式会增加冗余代码,不如事件监听简洁,所以仅作参考:
// 定义一个每次都会执行的工厂函数 angular.module('yourApp').factory('onAppStateChange', function() { return function() { console.log('test'); return Promise.resolve(); // resolve需要返回承诺或值 }; }); // 修改子状态配置 .state('app.home', { url: '/home', views: { 'menuContent': { templateUrl: 'pages/home.html', controller: 'homeCtrl' } }, resolve: { triggerFunc: onAppStateChange } }) .state('app.profile', { url: '/profile', views: { 'menuContent': { templateUrl: 'pages/profile.html', controller: 'profileCtrl' } }, resolve: { triggerFunc: onAppStateChange } })
内容的提问来源于stack exchange,提问作者Jis0
相关产品推荐
相关产品推荐

