Existe-t-il un moyen d'injecter une dépendance tardive à un module angular angulaire)? Voici ce que je veux dire:
Supposons que j'ai une application angular angulaire, définie comme:
// in app.js
var App = angular.module("App", []);
Et dans chaque page:
<html ng-app="App">
Plus tard, je rouvre l'application pour ajouter une logique en fonction des besoins de la page actuelle:
// in reports.js
var App = angular.module("App")
App.controller("ReportsController", ['$scope', function($scope) {
// .. reports controller code
}])
Supposons maintenant que l'un de ces bits de logique à la demande nécessite également ses propres dépendances (comme ngTouch
, ngAnimate
, ngResource
, etc.). Comment puis-je les attacher à l'application de base? Cela ne semble pas fonctionner:
// in reports.js
var App = angular.module("App", ['ui.event', 'ngResource']); // <-- raise error when App was already bootstrapped
Je réalise que je peux tout faire à l'avance, c'est-à-dire -
// in app.js
var App = angular.module("App", ['ui.event', 'ngResource', 'ngAnimate', ...]);
Ou définissez chaque module seul, puis injectez le tout dans l'application principale ( voir ici pour en savoir plus ):
// 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'])
Mais cela nécessitera que j'initialise l'application à chaque fois avec les dépendances de la page actuelle.
Je préfère inclure la base app.js
dans chaque page et introduisez simplement les extensions requises sur chaque page (reports.js
, home.js
, etc.), sans avoir à réviser la logique d'amorçage à chaque fois que j'ajoute ou supprime quelque chose.
Existe-t-il un moyen d'introduire des dépendances lorsque l'application est déjà amorcée? Quelle est la ou les manières idiomatiques considérées de le faire? Je penche vers cette dernière solution, mais je voulais voir si la façon dont je l'ai décrite pouvait également être faite. Merci.
Je l'ai résolu comme ceci:
référencer à nouveau l'application:
var app = angular.module('app');
puis Poussez vos nouvelles exigences dans le tableau des exigences:
app.requires.Push('newDependency');
Simple ... Obtenez une instance du module en utilisant le getter comme ceci: var app = angular.module ("App");
Ajoutez ensuite à la collection "requires" comme ceci: app.requires [app.requires.length] = "ngResource";
Quoi qu'il en soit, cela a fonctionné pour moi. BONNE CHANCE!
Selon cette proposition sur le Angular JS google group cette fonctionnalité n'existe pas pour le moment. J'espère que l'équipe principale décide d'ajouter cette fonctionnalité, pourrait l'utiliser moi-même .
Je me rends compte que c'est une vieille question, cependant, aucune réponse de travail n'a encore été fournie, alors j'ai décidé de partager comment je l'ai résolu.
La solution nécessite de forger Angular, vous ne pouvez donc plus utiliser CDN. Cependant, la modification est très petite, donc je suis surpris pourquoi cette fonctionnalité n'existe pas dans Angular.
J'ai suivi le lien vers les groupes Google fourni dans l'une des autres réponses à cette question. Là, j'ai trouvé le code suivant, qui a résolu le problème:
instanceInjector.loadNewModules = function (mods) {
forEach(loadModules(mods), function(fn) { instanceInjector.invoke(fn || noop); });
};
Lorsque j'ai ajouté ce code à la ligne 4414 dans le code source angular 1.5.0 (à l'intérieur de la fonction createInjector
, avant l'instruction return instanceInjector;
), Cela m'a permis pour ajouter des dépendances après l'amorçage comme ceci $injector.loadNewModules(['ngCookies']);
.
Si vous souhaitez ajouter plusieurs dépendances à la fois, vous pouvez les passer dans Push comme suit:
<script>
var app = angular.module('appName');
app.requires.Push('dependencyCtrl1', 'dependencyService1');
</script>
Depuis la version 1.6.7, il est désormais possible de charger des modules paresseusement après le démarrage de l'application à l'aide de $injector.loadNewModules([modules])
. Voici un exemple tiré de la documentation AngularJS:
app.factory('loadModule', function($injector) {
return function loadModule(moduleName, bundleUrl) {
return getScript(bundleUrl).then(function() { $injector.loadNewModules([moduleName]); });
};
})
Veuillez lire documentation complète sur loadNewModules car il y a des problèmes autour.
Il y a aussi un très bon exemple d'application par omkadiri l'utiliser avec ui-router.