Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AngularJS两个不同的$注射器_Angularjs_Dependency Injection_Angularjs Injector - Fatal编程技术网

AngularJS两个不同的$注射器

AngularJS两个不同的$注射器,angularjs,dependency-injection,angularjs-injector,Angularjs,Dependency Injection,Angularjs Injector,今天我发现,注入配置或提供程序的$injector与注入服务、工厂或控制器的$injector不同 这个$injectors的get()函数的工作原理不同 $injector来自配置或提供程序,无法获取()任何服务$injector.get('myService')抛出错误:[$injector:unpr]未知提供程序:myService,但$injector.has('myService')返回true。这很奇怪 $injector来自维修或控制器,工作正常 以下是一个代码示例,以便于更好地理

今天我发现,注入配置或提供程序的
$injector
与注入服务、工厂或控制器的
$injector
不同

这个$injectors的
get()
函数的工作原理不同

$injector
来自配置或提供程序,无法
获取()
任何服务
$injector.get('myService')
抛出
错误:[$injector:unpr]未知提供程序:myService
,但
$injector.has('myService')
返回true。这很奇怪

$injector
来自维修或控制器,工作正常

以下是一个代码示例,以便于更好地理解:

angular.module('app', [])

        .provider('myProvider', function ($injector) {
            this.$get = ['$injector', function (serviceInjector) {
                return {
                    providerInjector: $injector,
                    serviceInjector: serviceInjector
                };
            }];
        })

        .service('myService', function () {})

        .controller('myCtrl', function ($scope, myProvider) {
            var providerInjector = myProvider.providerInjector;
            var serviceInjector = myProvider.serviceInjector;

            console.log(providerInjector === serviceInjector); // -> false

            console.log(serviceInjector.has('myService')); // `serviceInjector` has `myService`
            console.log(getMyService(serviceInjector)); // `serviceInjector` can get `myService`

            console.log(providerInjector.has('myService')); // `providerInjector` has `myService` too!
            console.log(getMyService(providerInjector)); // but `providerInjector` can't get `myService`! =(

            function getMyService(injector) {
                try {
                    injector.get('myService');
                    return "OK";
                } catch (e) {
                    return e.toString();
                }
            }

        });

有人能解释为什么有两个不同的喷油器吗

我如何使用provider/config中的$injector来注入服务(当然是在服务初始化之后)


请注意,我使用角度1.3.13

确定。在阅读了你的评论之后,以下是我的答案

我在plunk中编辑了代码以使其正常工作,在调用providerInjector.get()时,代码应如下所示:

$scope.getMyServiceFromProviderInjector = function () {
        try {
                 myProvider.providerInjector.get('myServiceProvider');//here is change in provider name
                 return "OK";
            } catch (e) {
                 return e.toString();
            }
   };
根据以下内容,为配置和运行块引用:

  • 配置块-在提供程序注册和配置阶段执行。仅提供程序和常量 可以注入到配置块中。这是为了防止 在服务完全启动之前意外实例化服务 配置
  • 运行块-在创建注入器并用于启动应用程序后执行。只能使用实例和常量 注入运行块。这是为了防止进一步的系统故障 在应用程序运行时进行配置

这仅仅意味着,您无法在配置块内获取服务实例。

我在github上发现了这个问题:

在配置函数中,$injector是提供者注入器,而在运行函数中,$injector是实例注入器

一个是配置阶段的$injector(只能访问提供程序和常量),另一个是运行阶段的$injector。令人困惑的是,您可能认为$injector在从配置到运行的过程中会修改自身以包含新内容,但事实并非如此。它们是两个独立(尽管相关)的对象,具有各自的实例缓存

这种二分法的一个更深入的原因可能来自对$injector内部结构的深入了解,但它似乎已经非常核心了,两种类型的注入器几乎都有相同的行为,除了它们如何处理实例缓存中的“缓存未命中”

我们将在v2中检修喷油器,因此这将在那里得到修复(摆脱配置阶段是喷油器v2的目标之一)


看起来确实有两个不同的注入器,angular开发人员不会修复这种行为(在版本中,我不久前写了这篇文章,这解释了AngularJS的两个注入器的生命周期,即providerInjector和instanceInjector)


你的问题有点不清楚。你想在provider/config中实现什么?你能给出一个用例吗?用例?例如:在config部分通过$injector获取服务。当然,在服务初始化之后。在我的例子中(显示起来非常复杂)我在配置部分向提供程序添加回调。在回调中,我想使用我的服务。我无法帮助我,所以我使用$injector。当服务已经初始化时,将从控制器调用此回调。@Harry Burns请检查在plunkermyProvider.providerInjector.get('myServiceProvider')中工作的编辑代码将只返回服务的提供者包装,而不是服务本身。您没有回答我的第一个问题-为什么有两个$injector?有什么区别?以及如何获取“service$injector”在配置块中?那么您不认为这里有两个问题。1.为什么有两个不同的$injector。2.如何在配置中使用$injector。?第二个问题的答案是,您不能在配置块中使用$injector,因为在配置块中无法实例化服务。正如我在上面的回答中提到的。请检查以下内容:
.provider('instanceInjector', function () {

    var instanceInjector;

    function get() {
        return instanceInjector;
    }

    function exists() {
        return !!instanceInjector;
    }

    angular.extend(this, {
        get: get,
        exists: exists
    });

    this.$get = function ($injector) {
        instanceInjector = $injector;

        return {
            get: get,
            exists: exists
        };
    }
})

// We need to inject service somewhere.
// Otherwise $get function will be never executed
.run(['instanceInjector', function(instanceInjector){}])