Есть ли способ внедрить позднюю зависимость в уже загруженный модуль 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
и т. Д.), Без необходимости пересматривать логику начальной загрузки каждый раз, когда я что-то добавляю или удаляю.
Есть ли способ ввести зависимости, когда приложение уже загружено? Что считается идиоматическим способом (или способами) сделать это? Я склоняюсь к последнему решению, но хотел посмотреть, можно ли сделать то, что я описал. Спасибо.
Ответы:
Я решил это так:
снова обратитесь к приложению:
var app = angular.module('app');
затем поместите свои новые требования в массив требований:
app.requires.push('newDependency');
источник
app.requires
является массивом, поэтому, если вы добавляете несколько зависимостей (как в примере с отчетами), вы передаете их как отдельные аргументыpush
методу:app.requires.push('ui.event', 'ngResource');
или, если ваши дополнительные зависимости уже являются массивом:Array.prototype.push.apply(app.requires, ['ui.event', 'ngResource'])
Просто ... Получите экземпляр модуля с помощью геттера следующим образом: var app = angular.module ("App");
Затем добавьте в коллекцию «требуется», например: app.requires [app.requires.length] = «ngResource»;
Во всяком случае, у меня это сработало. УДАЧИ!
источник
Согласно этому предложению в группе Google Angular JS эта функциональность на данный момент не существует. Надеюсь, основная команда решит добавить эту функциональность и сможет использовать ее сама.
источник
Если вы хотите добавить сразу несколько зависимостей, вы можете передать их в push следующим образом:
<script> var app = angular.module('appName'); app.requires.push('dependencyCtrl1', 'dependencyService1'); </script>
источник
Я понимаю, что это старый вопрос, однако рабочего ответа пока нет, поэтому я решил рассказать, как я его решил.
Решение требует разветвления 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']);
.источник
Начиная с версии 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.
источник