Angularjs Can';t将喷油器从角度上收回
我的应用程序有两个模块:Angularjs Can';t将喷油器从角度上收回,angularjs,Angularjs,我的应用程序有两个模块: angular.module('components', []).directive('foo', function () { return {};}); angular.module('gaad', ['components']); 有一系列与这个模块相关的指令,我在这里不包括这些指令。 该应用程序运行良好。但是,当我试图检索模块gaad的喷油器时: var injector = angular.injector(['gaad', 'components']); /
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
应用程序现在相当大,我不知道应该在哪里查找bug。
所以我的问题是:我的问题的原因是什么?
编辑:
我能够复制我的问题:看来您还需要在喷油器中加入ng
var injector = angular.injector(['ng', 'b', 'a']);
发件人:
必须显式添加ng模块
在回答问题之前,我们需要注意每个应用程序只有一个喷油器实例,而不是每个模块。从这个意义上讲,不可能检索每个模块的喷油器。当然,如果我们使用顶级模块,它代表了整个应用程序。从这个意义上讲,应用程序和顶级模块似乎是等价的。这似乎是一个微妙的区别,但为了全面、正确地回答这个问题,理解这一点很重要 接下来,据我所知,您希望检索
$injector
,而不是创建它的新实例。问题是angular.injector
将为指定为参数的模块(应用程序)创建一个新的$injector
实例。这里必须明确指定主AngularJS模块(ng)。因此,在这个代码示例中:
var injector = angular.injector(['gaad', 'components']);
您试图从“gaad”和“components”模块中定义的组件创建新的注入器,显然,$compileProvider
未在自定义模块中定义将ng
模块添加到列表将通过创建新喷油器来“解决”问题——这可能是您不希望发生的事情
要实际检索与正在运行的应用程序关联的注入器实例,我们可以使用两种方法:
- 在AngularJS JavaScript中,最简单的解决方案就是注入
实例:$injector
- 从AngularJS世界之外-调用
其中[DOM element]是定义angular.element([DOM element]).injector()
的圆顶元素(或此元素的任何子元素)。更多信息请点击此处:ng app
还请注意,在单元测试之外,直接使用
$injector
不是很常见的场景。对于从AngularJS世界之外检索AngularJS服务来说,这可能是一个有用的想法。这里有更多信息:。问题在于Angular代码的执行流程。要在@pkozlowski.opensource的答案和相关注释上集成,请注意执行模块代码后,$injector
属性对DOM元素可用,因此当您访问该属性时(就像尝试console.log
它时),该属性仍然是未定义的
您可以通过简单地为日志功能的执行设置0超时来解决此问题(即,不需要以毫秒为单位的显式延迟)。这种方法之所以有效,是因为日志函数将在堆栈为空时执行,即Angular的引导完成并且DOM元素可以使用$injector
属性时执行
Angular术语中的另一个(也许更好)解决方案是将您的$injector
-访问代码包含在一个数据库中(另请参见)。然后,$injector
可以作为正常服务轻松地注入初始化功能。这是因为当所有引导终止时,运行块将排队并异步执行
下面您可以找到两个小提琴,每个解决方案一个
编辑
此外,通常不需要显式加载ng
模块。在正常情况下,ng
模型已自动加载,除非您希望手动引导Angular的代码。其中一个答案中引用的一段文档(不幸的是隐式地)提到Angular的手动引导过程,当您必须手动创建注入器并告诉它您要加载哪些模块时顺便说一句,如果您使用ng app,您不需要创建应用程序注入器。听到这个@maxisam很高兴!通过回答这些问题,我学到了很多:-)您发布的JSFIDLE返回未定义的作为注入器。。。如果您console.log(injector)
它将返回undefined
。这是伪代码吗?显然喷油器的可用性有一些延迟。如果你把它放在一个超时,你得到的注入器刚刚好。。。有趣。请看这里:。。。我不知道为什么会这样,我仍然没有找到延迟是什么。@blesh,是的,是伪代码,也许我不应该发布JSFIDLE。。。时间问题源于AngularJS需要时间来提升应用程序并在DOM元素上公开注入器。我将更改JSFIDLE并添加您的示例thnx!!!