【问题标题】:re-open and add dependencies to an already bootstrapped application重新打开并将依赖项添加到已引导的应用程序
【发布时间】:2013-09-23 10:02:29
【问题描述】:

有没有办法将后期依赖注入已经引导的角度模块?这就是我的意思:

假设我有一个站点范围的 Angular 应用程序,定义为:

// in app.js
var App = angular.module("App", []);

在每一页中:

<html ng-app="App">

稍后,我将根据当前页面的需要重新打开应用添加逻辑:

// in reports.js
var App = angular.module("App")
App.controller("ReportsController", ['$scope', function($scope) {
  // .. reports controller code
}])

现在,假设这些按需逻辑位之一也需要它们自己的依赖项(如ngTouchngAnimatengResource 等)。如何将它们附加到基本应用程序?这似乎不起作用:

// in reports.js
var App = angular.module("App", ['ui.event', 'ngResource']); // <-- raise error when App was already bootstrapped

我意识到我可以提前做所有事情,即 -

// in app.js
var App = angular.module("App", ['ui.event', 'ngResource', 'ngAnimate', ...]);

或者自己定义每个模块,然后将所有内容注入主应用程序 (see here for more):

// in reports.js
angular.module("Reports", ['ui.event', 'ngResource'])
.controller("ReportsController", ['$scope', function($scope) {
  // .. reports controller code
}])

// in home.js
angular.module("Home", ['ngAnimate'])
.controller("HomeController", ['$scope', '$http', function($scope, $http){
  // ...
}])

// in app.js, loaded last into the page (different for every page that varies in dependencies)
var App = angular.module("App", ['Reports', 'Home'])

但这需要我每次都使用当前页面的依赖项来初始化应用程序。

我更喜欢在每个页面中包含基本的app.js,并简单地为每个页面引入所需的扩展名(reports.jshome.js 等),而无需在每次添加或删除某些内容时修改引导逻辑。

当应用程序已经启动时,有没有办法引入依赖项?什么被认为是惯用的方式(或方式)来做到这一点?我倾向于后一种解决方案,但想看看我描述的方式是否也可以完成。谢谢。

【问题讨论】:

  • 你能给我你的最终工作代码,看看吗?
  • @user2393267 嗯,这么久了,我不知道我是否还有那个代码......对不起。我想我最终重新审视了设计,因为通常当我不得不破解一些东西时,这意味着我做得不对……但是,如果你仍然决心采用这种方法,answer below 似乎是一个不错的选择铅。

标签: angularjs dependency-injection bootstrapping


【解决方案1】:

我是这样解决的:

再次引用该应用:

var app = angular.module('app');

然后将您的新需求推送到需求数组:

app.requires.push('newDependency');

【讨论】:

  • 这对我有用 +1 我将它用于多个依赖项,例如 app.requires.push('doctorCtrl', 'doctorService');
  • 这拯救了我的架构。
  • 这对我不起作用。我正在按照描述动态添加依赖项,但 Angular 仍然无法从添加的模块中找到服务。
  • app.requires 是一个数组,因此如果您要添加多个 依赖项(如在您的报告示例中),您可以将它们作为单独的参数传递给push方法:app.requires.push('ui.event', 'ngResource'); 或者如果您的附加依赖项已经是一个数组:Array.prototype.push.apply(app.requires, ['ui.event', 'ngResource'])
  • 我有时会跳过投票,因为我不想登录,这次不行!谢谢!
【解决方案2】:

简单... 使用 getter 获取模块的实例,如下所示: var app = angular.module("App");

然后像这样添加到“requires”集合中: app.requires[app.requires.length] = "ngResource";

无论如何,这对我有用。祝你好运!

【讨论】:

  • 这对我有用!我有一个问题 - 为什么不使用:app.requires.push("ngResource")?
【解决方案3】:

根据this proposal on the Angular JS google group,此功能目前不存在。希望核心团队决定添加这个功能,可以自己使用。

【讨论】:

  • 是的,这似乎对那些不一定想建立 SPA 的人特别有用。
【解决方案4】:

如果你想一次添加多个依赖,你可以按如下方式在 push 中传递它们:

<script>
    var app = angular.module('appName');
    app.requires.push('dependencyCtrl1', 'dependencyService1');
</script>

【讨论】:

    【解决方案5】:

    我意识到这是一个老问题,但是还没有提供有效的答案,所以我决定分享我是如何解决它的。

    该解决方案需要分叉 Angular,因此您不能再使用 CDN。但是修改非常小,所以我很惊讶为什么 Angular 中不存在这个功能。

    我关注了one of the other answers 中提供的the link to google groups 来回答这个问题。在那里我找到了以下代码,解决了这个问题:

    instanceInjector.loadNewModules = function (mods) {
      forEach(loadModules(mods), function(fn) { instanceInjector.invoke(fn || noop); });
    };
    

    当我将此代码添加到 angular 1.5.0 源代码中的第 4414 行时(在 createInjector 函数内,在 return instanceInjector; 语句之前),它使我能够像这样在引导后添加依赖项 $injector.loadNewModules(['ngCookies']);

    【讨论】:

    • ? highest-voted answer (as of 6/26/2017) 有什么问题?看起来它是在您发布此内容之前一年多提供的;你的回答有什么好处吗?
    • @TheRedPea 嗯,没有什么问题,只是它没有解决我的问题,但这个答案确实
    • 它对你不起作用,因为我猜,你已经启动了你的应用程序?我也观察到了……
    • 在阅读了链接的 Google 社区帖子后,我更加确定引导是需要此类解决方案的原因。赞成是因为最初的问题是关于“已经启动的应用程序”,没有其他人解决(实际上 OP 可能说错了)
    【解决方案6】:

    从 1.6.7 版开始,现在可以在使用 $injector.loadNewModules([modules]) 引导应用程序后延迟加载模块。以下是取自 AngularJS 文档的示例:

    app.factory('loadModule', function($injector) {
       return function loadModule(moduleName, bundleUrl) {
         return getScript(bundleUrl).then(function() { $injector.loadNewModules([moduleName]); });
       };
    })
    

    请阅读full documentation about loadNewModules,因为它有一些陷阱。

    还有一个很不错的sample app by omkadiri 配合ui-router使用。

    【讨论】:

      猜你喜欢
      • 2012-12-30
      • 2012-11-01
      • 1970-01-01
      • 2011-12-02
      • 2014-09-30
      • 1970-01-01
      • 2016-02-29
      • 2015-08-11
      • 2016-07-16
      相关资源
      最近更新 更多