尽管存在服务,但未注入依赖项
Dependency not injected although service exists
所以我已经在 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所以如果我遗漏了一些概念或表述错误,请告诉我。
AngularJS 将 bootstrap 加载模块。在 bootstrapping 期间,所有依赖项都由注入器初始化。
angular.module('mainModule').service('ex2', .....);
当您通过 AJAX 执行上述操作时,会发生 在 之后 mainModule
已经被 bootstrapped。 service()
将使供应商排队等待 bootstrapping,但 bootstrapping 再也不会发生。
这来自 bootstrapping 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
被 bootstrap 添加为现有 mainModule
的依赖项。注入器应该看到此模块已排队等候 bootstrapping 并安装它。
希望对您有所帮助。
所以我已经在 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所以如果我遗漏了一些概念或表述错误,请告诉我。
AngularJS 将 bootstrap 加载模块。在 bootstrapping 期间,所有依赖项都由注入器初始化。
angular.module('mainModule').service('ex2', .....);
当您通过 AJAX 执行上述操作时,会发生 在 之后 mainModule
已经被 bootstrapped。 service()
将使供应商排队等待 bootstrapping,但 bootstrapping 再也不会发生。
这来自 bootstrapping 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
被 bootstrap 添加为现有 mainModule
的依赖项。注入器应该看到此模块已排队等候 bootstrapping 并安装它。
希望对您有所帮助。