Angular UI Router多resolve报错:v1.0.18异常v0.4.2正常求助
我来帮你分析并解决这个AngularJS与ui-router版本兼容的问题,你遇到的[$injector:unpr]错误是因为ui-router从v0.4.x升级到v1.x后,对resolve的处理逻辑发生了关键变化。
问题核心原因
你的代码在v0.4.2能正常运行,但v1.0.18报错,主要有两个关键点:
- resolve层级与执行优先级变化:你在state级别和视图内部同时定义了resolve,v0.4.2允许这种嵌套结构并能正确解析视图级的
dashboardData,但v1.x中state级resolve的执行优先级更高,导致控制器加载时视图级的dashboardData还未被注册到注入上下文。 - resolve键名冲突风险:如果你的
loadSequence函数返回的resolve对象用了控制器名称dashBoardCtrl作为键名,v1.x会干扰Angular对控制器的查找逻辑——它会尝试注入resolve的dashBoardCtrl值,而非你注册的控制器服务,进而导致后续依赖dashboardData找不到。
具体解决方案
方案1:将resolve合并到state级别
把视图内的dashboardData移到state级resolve,确保所有依赖在控制器加载前被解析:
$stateProvider.state('root.dashboard', { url: '/dashboard', resolve: { // 修改键名,避免与控制器名称冲突 loadDependencies: loadSequence('dashBoardCtrl'), // 将dashboardData移到state级统一处理 dashboardData: function(dbService){ return dbService.getDashboardData(); } }, views: { '': { templateUrl: BaseURL + '/templates/dashboard/index.html', controller: 'dashBoardCtrl' } } })
方案2:保留视图级resolve,调整state级resolve键名
如果想维持视图级resolve的结构,只需确保state级resolve的键名不与控制器重复:
$stateProvider.state('root.dashboard', { url: '/dashboard', resolve: { // 使用非控制器名称的键名,比如loadDeps loadDeps: loadSequence('dashBoardCtrl') }, views: { '': { templateUrl: BaseURL + '/templates/dashboard/index.html', controller: 'dashBoardCtrl', resolve: { dashboardData:function(dbService){ return dbService.getDashboardData(); } } } } })
方案3:检查loadSequence函数实现
确保loadSequence返回的是正确的resolve结构,不会干扰其他依赖项。比如它应该返回一个包含加载promise的对象,而非直接引用控制器:
// 示例loadSequence的正确实现(供参考) function loadSequence(dependencies) { return { deps: ['$q', '$ocLazyLoad', function($q, $ocLazyLoad) { var deferred = $q.defer(); $ocLazyLoad.load(dependencies).then(function() { deferred.resolve(); }); return deferred.promise; }] }; }
快速验证思路
你可以先临时移除state级的resolve: loadSequence('dashBoardCtrl'),测试视图级的dashboardData是否能被控制器正常注入。如果可以,说明问题确实出在state级resolve的键名或逻辑冲突上。
内容的提问来源于stack exchange,提问作者Kishore Vaishnav
相关产品推荐
相关产品推荐

