所以我已经在一个 Angular.js 项目上工作了一段时间,该项目将在比赛中使用,中途我意识到我需要一个插件系统来在运行时动态加载一些必要的代码。到目前为止,我发现 angular.js 不太适合在运行时加载服务。由于代码仅在比赛时提供给参赛者,我只能提供一个不起作用的示例。
// ex1.coffee
mainModule = angular.module('mainModule')
mainModule.service('needed', () ->
@neededFunc() ->
console.log "just an example"
return this
mainModule.service('ex1', ($injector) ->
@loadFile = (u, pluginName) ->
$.ajax
dataType: "script",
url: u,
data: null,
success: (jqxhr, textStatus) =>
$injector.invoke([pluginName, (plugin) =>
plugin.testFunc()
error: (jqxhr, textStatus, errorThrown) ->
console.log "couldn't find the script"
return this
// ex2.coffee
mainModule = angular.module('mainModule')
mainModule.service('ex2', (needed) ->
@testFunc = () ->
needed.neededFunc()
console.log "in this dynamically loaded file"
return this
隐式事物:有一个名为 mainModule 的现有模块。 Jquery和Angular之前已经包含在dom中了。 ex1.js 已经包含在 dom 中,而 ex2.js 尚未包含在 dom 中。 u 是文件 ex2.js 的 url,pluginName = "ex2"。当调用成功处理程序时,invoke 函数失败,表示 ex2Provider 不存在。但是,如果我在成功回调中断点并检查 mainModule._invokeQueue,确实存在一个服务名称为“ex2”的数组,因此模块内肯定有一个现有配方,但 $injector.invoke 调用仍然失败。如果我修改成功处理程序以调用 $injector.has pluginName,它将失败。有人可以告诉我模块如何了解此动态加载服务的提供者但无法使用 $injector 将其注入(inject)到函数调用中吗? 该项目是一个用 grunt 构建的 yeoman 项目。
仍在学习 Angular,因此如果我遗漏了某些概念或表述错误,请告诉我。
最佳答案
AngularJS 将在加载模块时引导该模块。在引导期间,所有依赖项均由注入(inject)器初始化。
angular.module('mainModule').service('ex2', .....);
当您通过 AJAX 执行上述操作时,它发生在 mainModule
已经引导之后。 service()
会将提供程序排队等待引导,但引导再也不会发生。
这是来自引导 Angular 手册。
You should call angular.bootstrap() after you've loaded or defined your modules. You cannot add controllers, services, directives, etc after an application bootstraps.
我认为您可以做的是创建一个新模块,并将其附加到现有模块。
因此您的 AJAX 代码可能如下所示。
angular.module('ex2Module',[]).service('ex2', .....);
angular.module('mainModule').requires.push('ex2Module');
$rootScope.$digest();
我无法对此进行测试,但我认为这将导致新模块 ex2Module
被引导并添加为现有 mainModule
的依赖项。注入(inject)器应该看到该模块已排队等待引导并安装它。
希望这有帮助。
关于jquery - 尽管服务存在但未注入(inject)依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28816329/