Angular:在UI Router中访问跨模块Provider的配置阶段问题
修正你的AngularJS Provider实现,以支持Config阶段访问
首先我注意到你代码里有几个小问题,先帮你修正,再说明如何在config阶段正常使用这个Provider:
1. 修正Provider的核心实现
你当前的代码存在变量名错误(opsInsightConstants应该是opsConstants),而且要让Provider能在config阶段被访问,需要调整Provider的结构——Provider构造函数在config阶段初始化,此时只能注入其他Provider或constant,不能直接注入普通服务。修正后的代码如下:
var app = angular.module('ops.services'); app.constant('opsConstants', { GID: 'UA1' }); app.provider('OpsConstantService', OpsConstantService); // Provider构造函数不需要注入opsConstants,留到$get方法中处理 function OpsConstantService() { // 可配置的常量存储,允许在config阶段修改 var customConstants = null; // 暴露给config阶段的配置方法 this.setCustomConstants = function(newConstants) { customConstants = newConstants; }; // $get方法在run阶段执行,返回最终的服务实例 this.$get = ['opsConstants', function(opsConstants) { // 优先使用config阶段设置的常量,否则用默认的opsConstants var finalConstants = customConstants || opsConstants; return { OPSCONSTANTS: finalConstants }; }]; }
2. 在应用模块的Config阶段访问Provider
你的主应用模块已经依赖了ops.services,现在可以在config函数中注入OpsConstantServiceProvider(注意后缀必须是Provider)来操作它:
var opsApp = angular.module('opsApp', ['ops.services']); opsApp.config(['OpsConstantServiceProvider', function(OpsConstantServiceProvider) { // 在这里修改常量,比如替换GID的值 OpsConstantServiceProvider.setCustomConstants({ GID: 'UA2' }); // 如果只是想读取默认常量,其实直接注入opsConstant到config里更简单,不过用Provider也能实现需求 }]);
3. 在业务代码中使用最终的服务
在run阶段之后,你就可以像普通服务一样注入OpsConstantService来获取常量:
opsApp.controller('SampleController', ['OpsConstantService', function(OpsConstantService) { console.log(OpsConstantService.OPSCONSTANTS.GID); // 输出UA2(如果config阶段修改过) }]);
关键提示
- AngularJS里只有Provider能在config阶段被注入,注入时必须在服务名后加上
Provider后缀。 - 你的原始代码把
opsConstants注入到Provider构造函数是错误的,因为config阶段只能访问Provider和Constant类型,普通服务还未初始化。 - 如果只是单纯想在config阶段读取常量,直接注入
opsConstants到config函数里会更简洁,但如果需要动态修改常量再提供给业务代码,用Provider的方式就很合适。
内容的提问来源于stack exchange,提问作者StrugglingCoder
相关产品推荐
相关产品推荐

