¿Hay alguna manera de inyectar una dependencia tardía a un módulo angular ya iniciado? Esto es lo que quiero decir:
Digamos que tengo una aplicación angular en todo el sitio, definida como:
// in app.js
var App = angular.module("App", []);
Y en cada página:
<html ng-app="App">
Más tarde, reabriré la aplicación para agregar lógica según las necesidades de la página actual:
// in reports.js
var App = angular.module("App")
App.controller("ReportsController", ['$scope', function($scope) {
// .. reports controller code
}])
Ahora, decir que uno de esos bits a la carta de la lógica también requiere sus propias dependencias (como ngTouch
, ngAnimate
, ngResource
, etc). ¿Cómo puedo adjuntarlos a la aplicación base? Esto no parece funcionar:
// in reports.js
var App = angular.module("App", ['ui.event', 'ngResource']); // <-- raise error when App was already bootstrapped
Me doy cuenta de que puedo hacer todo por adelantado, es decir,
// in app.js
var App = angular.module("App", ['ui.event', 'ngResource', 'ngAnimate', ...]);
O defina cada módulo por sí solo y luego inyecte todo en la aplicación principal ( consulte aquí para obtener más información ):
// 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'])
Pero esto requerirá que inicialice la aplicación cada vez con las dependencias de la página actual.
Yo prefiero incluir el básico app.js
en cada página y simplemente presento las extensiones necesarias para cada página ( reports.js
, home.js
, etc.), sin tener que revisar la lógica de arranque cada vez que puedo añadir o eliminar algo.
¿Hay alguna forma de introducir dependencias cuando la aplicación ya está iniciada? ¿Cuál se considera la forma (o formas) idiomáticas de hacer esto? Me inclino hacia la última solución, pero quería ver si la forma que describí también se podría hacer. Gracias.
Respuestas:
Lo resolví así:
referencia la aplicación nuevamente:
luego empuje sus nuevos requisitos a la matriz de requisitos:
fuente
app.requires
es una matriz, por lo que si está agregando varias dependencias (como en su ejemplo de Informes), las pasa como argumentos separados alpush
método:app.requires.push('ui.event', 'ngResource');
o si sus dependencias adicionales ya son una matriz:Array.prototype.push.apply(app.requires, ['ui.event', 'ngResource'])
Simple ... Obtenga una instancia del módulo usando el getter como este: var app = angular.module ("App");
Luego agregue a la colección "requiere" de esta manera: app.requires [app.requires.length] = "ngResource";
De todos modos, esto funcionó para mí. ¡BUENA SUERTE!
fuente
Según esta propuesta en el grupo de google de Angular JS esta funcionalidad no existe a partir de este momento. Con suerte, el equipo central decide agregar esta funcionalidad, podría usarla yo mismo.
fuente
Si desea agregar varias dependencias a la vez, puede pasarlas en push de la siguiente manera:
fuente
Me doy cuenta de que esta es una pregunta antigua, sin embargo, aún no se ha proporcionado una respuesta funcional, por lo que decidí compartir cómo la resolví.
La solución requiere bifurcar Angular, por lo que ya no puede usar CDN. Sin embargo, la modificación es muy pequeña, por lo que me sorprende que esta función no exista en Angular.
Seguí el enlace a los grupos de Google que se proporcionó en una de las otras respuestas a esta pregunta. Allí encontré el siguiente código, que resolvió el problema:
Cuando agregué este código a la línea 4414 en el código fuente angular 1.5.0 (dentro de la
createInjector
función, antes de lareturn instanceInjector;
declaración), me permitió agregar dependencias después de arrancar de esta manera$injector.loadNewModules(['ngCookies']);
.fuente
Desde la versión 1.6.7, ahora es posible cargar módulos de forma diferida después de que la aplicación haya sido arrancada usando
$injector.loadNewModules([modules])
. A continuación se muestra un ejemplo tomado de la documentación de AngularJS:Lea la documentación completa sobre loadNewModules, ya que existen algunas trampas.
También hay una muy buena aplicación de muestra de omkadiri que la usa con ui-router.
fuente