无法从angular度检索喷油器

我有两个模块的应用程序:

angular.module('components', []).directive('foo', function () { return {};}); angular.module('gaad', ['components']); 

这里有一堆与这个模块相关的指令。 应用程序工作正常。 但是,当我试图检索模块gaad注入器:

 var injector = angular.injector(['gaad', 'components']); //called after 'gaad' module initialization 

错误被抛出:

 Uncaught Error: Unknown provider: $compileProvider from components 

现在的应用程序是相当大的,我不知道应该在哪里寻找错误。 所以我的问题是: 什么可能是我的问题的原因?

编辑:我能够复制我的问题: http : //jsfiddle.net/selbh/ehmnt/11/

在回答问题之前,我们需要注意的是, 每个应用程序只有一个注入器实例,而不是每个模块 。 从这个意义上说,不可能为每个模块检索一个注入器。 当然,如果我们采用顶级模块,它代表了整个应用程序。 在这个意义上,应用程序和顶级模块似乎是等价的。 这可能看起来像一个微妙的差异,但重要的是要充分和正确地回答这个问题。

接下来,从我能理解的你想要检索 $injector而不是创build一个新的实例。 问题是angular.injector将为模块(应用程序)创build一个新的$injector实例作为参数。 这里主要的AngularJS模块(ng)必须明确指定。 所以,在这个代码示例中:

 var injector = angular.injector(['gaad', 'components']); 

你正尝试从'gaad'和'components'模块中定义的组件创build一个新的注入器,显然$compileProvider没有在你的自定义模块中定义。 ng模块添加到列表中将通过创build一个新的注入器“解决”问题 – 这可能是您不希望发生的事情。

要实际检索与正在运行的应用程序关联的注入器实例,我们可以使用2种方法

  • 从AngularJS JavaScript中最简单的解决scheme是只注入$injector实例: http : //docs.angularjs.org/api/angular.injector
  • 从AngularJS世界的外部调用angular.element([DOM element]).injector()其中[DOM element]是定义了ng-app (或者这个元素的任何子元素)的dome元素。 更多信息在这里: http : //docs.angularjs.org/api/angular.element

这里是显示喷油器检索2种方法的jsFiddle: http : //jsfiddle.net/xaQzb/

另请注意,在unit testing之外,直接使用$injector并不是很常见的情况。 从AngularJS世界以外检索AngularJS服务可能是有用的想法。 更多信息: 从传统代码中调用Angular JS 。

看来你还需要在注入器中包含ng。

 var injector = angular.injector(['ng', 'b', 'a']); 

来自: AngularJS:注射器

ng模块必须明确添加。

问题在于Angular代码的执行stream程。 要集成@ pkozlowski.opensource的答案和相关注释,请注意$injector模块代码执行后, $injector属性可用于DOM元素,以便当您访问该属性时(如尝试console.log时)财产仍然是undefined

你可以通过设置一个0超时来解决这个问题,即执行日志function(即不需要明确的毫秒延迟)。 这个黑客工作,因为日志function将被执行时,堆栈是空的,也就是当Angular的引导已经完成, $injector属性是可用的DOM元素。

Angular的另一个(也许更好的)解决scheme是将你的$injector代码包含在运行块中 (参见相关的API )。 $injector然后可以被容易地注入初始化函数作为正常的服务。 这是有效的,因为当所有引导已经终止时,运行块排队并且asynchronous执行。

下面你可以find两个小提琴,每个解决scheme一个。

0超时jsFiddle

运行块jsFiddle

编辑

另外,通常不需要显式加载ng模块。 在正常情况下, ng模型已经自动加载,除非你想执行Angular代码的手动引导。 其中一个答案中引用的文档引用(隐含地,不幸地)Angular的手动引导程序,当你必须手动创build注入器,并告诉它要加载哪些模块