Angular 1.5中使用stateProvider的resolve后向控制器传undefined值
咱们来一步步梳理你遇到的这个问题——用$stateProvider的resolve功能后,控制器拿到undefined值,结合你给出的代码片段,常见的原因和解决办法如下:
1. Resolve函数未正确返回值或Promise
这是最常见的坑!如果你的resolve函数是异步操作(比如请求后端数据),必须返回一个Promise,否则Angular不会等待数据加载完成就直接初始化控制器,自然拿到的就是undefined。
举个反例(错误写法):
resolve: { userInfo: function(UserApi) { UserApi.getUser(); // 只调用了方法,但没返回Promise } }
正确的写法应该是返回Promise:
resolve: { userInfo: function(UserApi) { return UserApi.getUser(); // 把异步请求的Promise返回给resolve } }
如果是同步值(比如你代码里的env工厂),也要确保明确返回:
resolve: { domain: function(env) { return env.domain; // 明确返回需要传递的domain值 } }
2. 控制器注入的参数名称不匹配
Angular是按名称大小写敏感匹配resolve的key和控制器注入参数的。比如你resolve里定义的是domain,控制器里写成Domain或者domainData,都会拿到undefined。
结合你的代码,正确的控制器注入应该是这样:
app.controller('YourCtrl', function(domain) { console.log(domain); // 这里的参数名必须和resolve里的key完全一致 });
3. preAssignBindingsEnabled与组件式控制器的冲突
你代码里设置了$compileProvider.preAssignBindingsEnabled(true),这是为了兼容旧的绑定方式,但如果你的控制器是Angular 1.5的component组件,要确保resolve的值正确绑定到组件的输入属性上:
.state('yourState', { url: '/your-path', component: 'yourComponent', resolve: { domain: function(env) { return env.domain; } }, bindings: { domain: '<' // 把resolve的domain绑定到组件的输入属性 } })
组件内部也要对应定义输入属性:
app.component('yourComponent', { bindings: { domain: '<' }, controller: function() { console.log(this.domain); // 通过this.domain访问resolve传递的值 } });
4. Resolve的Promise被拒绝但未捕获
如果resolve里的异步操作失败(比如API请求报错),Promise被rejected,Angular会跳过控制器初始化,但有时候错误会被静默处理,导致你误以为是值为undefined。可以添加全局事件监听来排查:
app.run(function($rootScope) { $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) { console.error('Resolve阶段出错:', error); // 打印具体错误原因 }); });
5. 多余的self = this可能引发作用域问题
你在config函数里写了self = this;,这里的this在config阶段是provider的上下文,这个不必要的赋值可能会导致意外的作用域干扰,建议直接删掉这行代码。
内容的提问来源于stack exchange,提问作者Elad Benda2

