Angular 当服务注入到其他地方时提供商配置重置

Angular provider configuration reset when service injected into somewhere else

描述这一点并不容易,但基本上我有一项设置为提供商的服务,因此我可以对其进行配置。它有一个在我的项目中使用的 APIs 数组,最初是空的。各种配置块可以向数组添加一个 API 对象,这似乎是可行的。我每次 console.log 输出并且数组在增长。

然后我将我的服务注入其他东西(在本例中为 $http 拦截器函数)并使用服务方法 return 数组,但每次我得到一个空数组。

我认为它的工作方式是所有配置首先阻塞 运行,然后被拦截的 $http 调用发生,所以数组应该充满 API s 到它被拦截的时候。

无论如何,这是一些代码

angular.module('authModule').provider('authService', function(){

    var _apis = [];

    return({
        addApi: addApi,
        $get: instantiateAuth
    });

    function addApi(newApi){
        _apis.push(newApi);
        console.log("API added", _apis);
    }

    function instantiateAuth() {
        return({
            getApis: function(){
                console.log("Getting APIs", _apis);
                return _apis;
            }
        });
    }

})


.config(function($httpProvider){

    $httpProvider.interceptors.push(function($log, $rootScope, $q) {
        return {
            request: function(config) {
                var injector = angular.injector(['ng', 'authModule']);
                var authService = injector.get('authService');
                console.log("apis", authService.getApis());
            }
        };
    });

});

以及示例配置块

angular.module('myModule').config(function ($provide, authServiceProvider) {

    authServiceProvider.addApi({
        url: 'https://apiurl.com',
        other: 'stuff'
    });

    authServiceProvider.addApi({
        url: 'https://apiurl2.com',
        other: 'stuff'
    });

});

因此,每次在配置块中调用 appApi 方法时(此处两次),此行输出数组 console.log("API added", _apis);它在第一次调用后正确输出 1 个项目,在第二次调用后正确输出两个项目。

当此代码 - authService.getApis() - 在第一次拦截 HTTP 调用时触发时,它会将一个空数组记录到控制台。

如有任何帮助,我们将不胜感激。

编辑:

问题似乎出在这一行

var 注入器 = angular.injector(['ng', 'authModule']);

每次发生这种情况时,我的提供商似乎都是 reset/recreated,所以我可能误解了如何使用注射器。我最初只是在函数参数中以正常方式注入我的 authService 但我得到了循环依赖(我的 auth 服务需要打开模态 window,但是 angular-ui 模态依赖在 http 服务上,我的 http 调用被拦截以检查我的 auth 服务用户是否已通过身份验证:( )

是的,angular.injector(['ng', 'authModule'])本质上是创建一个新的注入器实例(应用程序实例,通俗地说):

angular.injector(['authModule']) !== `angular.injector(['authModule'])

ng 模块默认加载,不必明确指定。单例服务仅在同一个注入器实例中是单例:

injector.get('authService') === injector.get('authService');

但是

angular.injector(['authModule']).get('authService') !== `angular.injector(['authModule']).get('authService')

要重用当前注入器实例(这在几乎所有情况下都是理想的行为)应该使用 $injector service

$httpProvider.interceptors.push(function($log, $rootScope, $q, $injector) {
    return {
        request: function(config) {
            var authService = $injector.get('authService');
        }
    };
});

$injector.get 是解决循环依赖的已知且直接的解决方案。