Angular跨模块服务注入问题:含Provider及共享-核心模块场景
如何将某模块内的服务注入到另一模块的Provider中?
嘿,在AngularJS里干这事得先搞懂它的配置阶段和运行阶段差异——Provider是在配置阶段初始化的,这时候普通的Service/Factory还没完成实例化,没法直接注入。通常有两种靠谱的处理方式:
- 如果目标服务是用
.provider()定义的(自带Provider实例),那可以直接在配置阶段注入[服务名]Provider,然后在Provider的$get方法里拿到服务实例来使用。 - 如果服务是用
.service()或.factory()创建的(没暴露Provider接口),那只能等运行阶段所有服务都初始化完成后,再把服务实例注入到Provider的实例里。
先看你给出的Core模块代码,你居然在Core里重复注册了一次PersistSettingsService!这会直接覆盖Shared模块里的原服务,绝对是问题的根源之一,先把这行删掉!Core已经依赖了Shared模块,所以Shared里的服务会自动在Core模块中可用,完全不需要重复注册。
接下来分两种场景给你解决方法:
情况1:PersistSettingsService是用.provider()定义的
如果Shared模块里的这个服务是用.provider()实现的,那直接在Core的配置阶段注入它的Provider即可:
// Shared模块的定义示例 angular.module('shared', []) .provider('PersistSettingsService', function() { // 可选:添加服务的配置逻辑 this.setDefaultLocale = function(locale) { /* ... */ }; // 服务实例化逻辑 this.$get = function() { return { getSettings: function() { // 返回你的配置数据 return { locale: 'zh-CN' }; } }; }; }); // Core模块的正确配置 angular.module('core', ['auth', 'shared']) .constant('moment', moment) .provider('Localisation', function(PersistSettingsServiceProvider) { // 可选:用Provider做前置配置 PersistSettingsServiceProvider.setDefaultLocale('en-US'); // 在$get方法中注入真正的服务实例 this.$get = function(PersistSettingsService) { return { getCurrentLocale: function() { // 直接调用Shared模块服务的方法 return PersistSettingsService.getSettings().locale; } }; }; }) // 注意:务必删除Core里重复注册的PersistSettingsService! .service('ModuleLazyLoaderService', ModuleLazyLoaderService) .service('PermissionsService', PermissionsService);
情况2:PersistSettingsService是用.service()/.factory()定义的
如果这个服务是用.service()或.factory()创建的,没法在配置阶段直接注入,那我们换个思路:在运行阶段把服务实例传给Provider:
// Shared模块的定义示例 angular.module('shared', []) .service('PersistSettingsService', function() { this.getSettings = function() { return { locale: 'zh-CN' }; }; }); // Core模块的正确配置 angular.module('core', ['auth', 'shared']) .constant('moment', moment) .provider('Localisation', function() { // 声明变量用于存储服务实例 let _persistSettingsService; // 对外暴露方法,接收服务实例 this.setPersistSettingsService = function(service) { _persistSettingsService = service; }; this.$get = function() { return { getCurrentLocale: function() { // 使用存储的服务实例 return _persistSettingsService.getSettings().locale; } }; }; }) .service('ModuleLazyLoaderService', ModuleLazyLoaderService) .service('PermissionsService', PermissionsService) // 在run阶段注入服务并传递给Provider .run(function(LocalisationProvider, PersistSettingsService) { LocalisationProvider.setPersistSettingsService(PersistSettingsService); });
调整完之后应该就能正常注入使用了,核心就是别重复注册服务,摸清楚AngularJS的阶段限制~
内容的提问来源于stack exchange,提问作者Joe Warner
相关产品推荐
相关产品推荐

