【发布时间】:2015-05-03 04:34:46
【问题描述】:
所以我一直在研究一个将在比赛中使用的 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 和 pluginName = "ex2" 的 URL。当调用成功处理程序时,调用函数失败,表示 ex2Provider 不存在。但是,如果我在成功回调中设置断点并检查 mainModule._invokeQueue,确实存在一个服务名称为“ex2”的数组,因此它在模块中肯定有一个现有的配方,但 $injector.invoke 调用仍然失败。如果我修改成功处理程序以调用 $injector.has pluginName,它会失败。有人能告诉我模块如何知道这个动态加载的服务的提供者,但不能用 $injector 将它注入到函数调用中吗? 该项目是一个用 grunt 构建的 yeoman 项目。
仍在学习 Angular,所以如果我遗漏了一些概念或说错了,请告诉我。
【问题讨论】:
-
您确定丢失的是 ex2Provider 吗?通常 AngularJS 将依赖错误作为一个链给出,人们通过假设链中的第一个引用是触发错误的原因而误读了错误。
-
基于示例。 ex2 将失败是依赖
needed不存在。这会导致 ex2Provider 注入失败。 -
@MathewFoscarini - 在 ajax 加载 ex2.js 时,ex1.js 已经运行,因此需要并且 ex1 应该已经存在(至少作为配方)在 mainModule 中。每当我尝试将 ex2 注入该函数时,如果它以前不存在,它是否也不应该实例化并注入需要,或者如果它已经被实例化则只注入?在该成功处理程序中,我确认所有 3 项服务都存在配方。如果配方尚未实例化,$injector.has 或 $injector.invoke 是否会抛出异常?如果是这样,我可以手动实例化服务吗?
标签: jquery angularjs node.js coffeescript yeoman