Czy istnieje sposób na wstrzyknięcie późnej zależności do już załadowanego modułu kątowego? Oto o co mi chodzi:
Załóżmy, że mam aplikację kątową obejmującą całą witrynę, zdefiniowaną jako:
// in app.js
var App = angular.module("App", []);
I na każdej stronie:
<html ng-app="App">
Później ponownie otwieram aplikację, aby dodać logikę w oparciu o potrzeby bieżącej strony:
// in reports.js
var App = angular.module("App")
App.controller("ReportsController", ['$scope', function($scope) {
// .. reports controller code
}])
Teraz mówią, że jeden z tych bitów na żądanie logiki wymaga również własne zależności (jak ngTouch
, ngAnimate
, ngResource
itp). Jak mogę dołączyć je do aplikacji podstawowej? To nie wydaje się działać:
// in reports.js
var App = angular.module("App", ['ui.event', 'ngResource']); // <-- raise error when App was already bootstrapped
Zdaję sobie sprawę, że mogę wszystko zrobić z góry, tj.
// in app.js
var App = angular.module("App", ['ui.event', 'ngResource', 'ngAnimate', ...]);
Lub zdefiniuj każdy moduł osobno, a następnie wstrzyknij wszystko do głównej aplikacji ( zobacz tutaj po więcej ):
// 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'])
Ale będzie to wymagało za każdym razem zainicjowania aplikacji z zależnościami bieżącej strony.
Wolę to podstawowy app.js
w każdej strony i po prostu przedstawić wymaganych rozszerzeń (na każdej stronie reports.js
, home.js
itp), bez konieczności rewizji za każdym logiczny ładującego dodać lub usunąć coś.
Czy istnieje sposób na wprowadzenie zależności, gdy aplikacja jest już załadowana? Jaki jest idiomatyczny sposób (lub sposoby), aby to zrobić? Skłaniam się ku temu drugiemu rozwiązaniu, ale chciałem sprawdzić, czy sposób, który opisałem, również da się zrobić. dzięki.
Odpowiedzi:
Rozwiązałem to w ten sposób:
ponownie odwołaj się do aplikacji:
var app = angular.module('app');
następnie umieść nowe wymagania w tablicy wymagań:
app.requires.push('newDependency');
źródło
app.requires
jest tablicą, więc jeśli dodajesz wiele zależności (jak w przykładzie Reports), przekazujesz je jako oddzielne argumenty dopush
metody:app.requires.push('ui.event', 'ngResource');
lub jeśli twoje dodatkowe zależności są już tablicą:Array.prototype.push.apply(app.requires, ['ui.event', 'ngResource'])
Proste ... Pobierz instancję modułu za pomocą metody pobierania w następujący sposób: var app = angular.module ("App");
Następnie dodaj do kolekcji „require” w następujący sposób: app.requires [app.requires.length] = "ngResource";
W każdym razie to zadziałało dla mnie. POWODZENIA!
źródło
Zgodnie z tą propozycją w grupie Google Angular JS ta funkcjonalność nie istnieje w tej chwili. Miejmy nadzieję, że główny zespół zdecyduje się dodać tę funkcję, przydałby się sam.
źródło
Jeśli chcesz dodać wiele zależności jednocześnie, możesz przekazać je w trybie push w następujący sposób:
<script> var app = angular.module('appName'); app.requires.push('dependencyCtrl1', 'dependencyService1'); </script>
źródło
Zdaję sobie sprawę, że to stare pytanie, jednak nie otrzymałem jeszcze działającej odpowiedzi, więc postanowiłem podzielić się, jak je rozwiązałem.
Rozwiązanie wymaga rozwidlenia Angulara, więc nie możesz już używać CDN. Jednak modyfikacja jest bardzo mała, więc jestem zaskoczony, dlaczego ta funkcja nie istnieje w Angular.
Skorzystałem z linku do grup Google, który został podany w jednej z pozostałych odpowiedzi na to pytanie. Tam znalazłem następujący kod, który rozwiązał problem:
instanceInjector.loadNewModules = function (mods) { forEach(loadModules(mods), function(fn) { instanceInjector.invoke(fn || noop); }); };
Kiedy dodałem ten kod do linii 4414 w kątowym kodzie źródłowym 1.5.0 (wewnątrz
createInjector
funkcji, przedreturn instanceInjector;
instrukcją), umożliwiło mi to dodanie zależności po załadowaniu w ten sposób$injector.loadNewModules(['ngCookies']);
.źródło
Od wersji 1.6.7 możliwe jest teraz opóźnione ładowanie modułów po załadowaniu aplikacji przy użyciu
$injector.loadNewModules([modules])
. Poniżej przykład zaczerpnięty z dokumentacji AngularJS:app.factory('loadModule', function($injector) { return function loadModule(moduleName, bundleUrl) { return getScript(bundleUrl).then(function() { $injector.loadNewModules([moduleName]); }); }; })
Przeczytaj pełną dokumentację dotyczącą loadNewModules ponieważ istnieje kilka pułapek wokół niego.
Jest też bardzo dobra przykładowa aplikacja omkadiri, która używa jej z routerem ui.
źródło