Повторно открыть и добавить зависимости к уже загрунтованному приложению

Есть ли способ вставить позднюю зависимость к уже загрунтованному модулю angular? Вот что я имею в виду:

Скажем, что у меня есть приложение 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
}])

Теперь скажем, что один из этих битов логики по требованию также требует собственных зависимостей (например, ngTouch, ngAnimate, ngResource и т.д.). Как я могу прикрепить их к базовому приложению? Это не работает:

// 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', ...]);

Или определите каждый модуль самостоятельно, а затем введите все в основное приложение (подробнее см. здесь):

// 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.js, home.js и т.д.), не пересматривая логику начальной загрузки каждый раз, когда я добавляю или удаляю что-либо.

Есть ли способ ввести зависимости, когда приложение уже загружено? Что считается идиоматическим способом (или путями) для этого? Я склоняюсь к последнему решению, но хотел бы посмотреть, можно ли сделать так, как я описал. спасибо.

Ответ 1

Я решил это так:

снова ссылайтесь на приложение:

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

а затем введите новые требования в массив требований:

app.requires.push('newDependency');

Ответ 2

Простой... Получите экземпляр модуля, используя getter следующим образом: var app = angular.module( "App" );

Затем добавьте в коллекцию "требуется": app.requires [app.requires.length] = "ngResource";

Во всяком случае, это сработало для меня. УДАЧА!

Ответ 3

В соответствии с этим предложением в группе Angular JS google эта функция не существует с этого момента. Надеюсь, основная команда решит добавить эту функциональность, может использовать ее самостоятельно.

Ответ 4

Если вы хотите добавить сразу несколько зависимостей, вы можете передать их следующим образом:

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

Ответ 5

Я понимаю, что это старый вопрос, однако рабочий ответ еще не предоставлен, поэтому я решил поделиться тем, как я его решил.

Для решения требуется forking Angular, поэтому вы больше не можете использовать CDN. Однако модификация очень мала, поэтому я удивлен, почему эта функция не существует в Angular.

Я следил за ссылка на группы google, которая была предоставлена ​​в одном из других ответов к этому вопросу. Там я нашел следующий код, который решил проблему:

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

Когда я добавил этот код в строку 4414 в исходном коде angular 1.5.0 (внутри функции createInjector, перед оператором return instanceInjector;), он позволил мне добавить зависимости после начальной загрузки, например, $injector.loadNewModules(['ngCookies']);.

Ответ 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]); });
   };
})

Пожалуйста, прочитайте полную документацию о loadNewModules, так как есть некоторые ошибки вокруг этого.

Есть также очень хороший пример приложения от omkadiri, использующего его с ui-router.