Не удается извлечь инжектор из углового
у меня есть приложение с двумя модулями:
angular.module('components', []).directive('foo', function () { return {};});
angular.module('gaad', ['components']);
есть куча директив, связанных с этими модулями, которые я здесь не включаю.
Приложение работает нормально. Однако, когда я пытаюсь получить инжектор для модуля gaad
:
var injector = angular.injector(['gaad', 'components']); //called after 'gaad' module initialization
возникает ошибка:
Uncaught Error: Unknown provider: $compileProvider from components
приложения довольно большой, и я понятия не имею, где я должен искать ошибки. Так что мой вопрос:что может быть причиной моего проблемы?
EDIT: Я смог воспроизвести свою проблему:http://jsfiddle.net/selbh/ehmnt/11/
3 ответа:
прежде чем ответить на вопрос, мы должны отметить, что есть только один экземпляр инжектора на приложение, а не на модуль. В этом смысле невозможно получить инжектор для каждого модуля. Конечно, если мы возьмем модуль верхнего уровня, он представляет собой все приложение. В этом смысле приложение и модуль верхнего уровня кажутся эквивалентными. Это может показаться тонкой разницей, но важно понять, чтобы полностью и правильно ответить на этот вопрос вопрос.
Далее, из того, что я могу понять, вы хотели бы извлечь the
$injector
и не создавать новый экземпляр. Дело в том, чтоangular.injector
создать новый$injector
экземпляр для модулей (приложение), указанных в качестве аргументов. Здесь основной модуль AngularJS (ng) должен быть указан явно. Итак, в этом примере кода:var injector = angular.injector(['gaad', 'components']);
вы пытались создать новый инжектор из компонентов, определенных в модулях "gaad" и "components" и очевидно
$compileProvider
не определен в пользовательских модулях. добавлятьng
модуль в списке "решит" проблему, создав новый инжектор - то, что вы, вероятно, не хотите, чтобы произошло.чтобы фактически получить экземпляр инжектора, связанный с запущенным приложением мы можем использовать 2 метода:
- из AngularJS JavaScript самое простое решение-просто ввести
$injector
экземпляр: http://docs.angularjs.org/api/angular.injector- из-за пределов AngularJS world-call
angular.element([DOM element]).injector()
где [элемент DOM] является элементом купола, гдеng-app
была определена (или любой дочерний элемент этого элемента). Более подробная информация здесь:http://docs.angularjs.org/api/angular.elementвот jsFiddle, показывающий 2 метода извлечения инжектора:http://jsfiddle.net/xaQzb/
Пожалуйста, обратите внимание что с помощью
$injector
непосредственно не очень распространенный сценарий за пределами модульного тестирования. Это может быть полезно для получения услуг AngularJS из-за пределов мира AngularJS. Более подробная информация здесь:вызов угловой JS из устаревшего кода.
похоже, вам также нужно включить ng в инжектор.
var injector = angular.injector(['ng', 'b', 'a']);
модуль ng должен быть явно добавлен.
проблема заключается в потоке выполнения кода Angular. Интегрировать на @pkozlowski.ответ opensource и связанные с ним комментарии, обратите внимание, что
$injector
свойство становится доступным для элементов DOM после выполнения кода модуля, так что при доступе к свойству (как при попыткеconsole.log
it) свойство все равно будетundefined
.вы можете решить эту проблему, просто установив тайм-аут 0 для выполнения функции ведения журнала (т. е. без явной задержки миллисекунды необходимы). Этот хак работает, потому что функция ведения журнала будет выполняться, когда стек пуст, то есть когда загрузка Angular закончилась и
$injector
свойство доступно для элементов DOM.другое (возможно, лучшее) решение в жаргоне Angular было бы включить ваш
$injector
-доступ к коду в запустить блок (см. Также связанный API). Элемент$injector
смогло после этого легко быть впрыснуто в функцию инициализации как a нормальное обслуживание. Это работает, потому что блоки запуска помещаются в очередь и выполняются асинхронно, когда вся начальная загрузка завершена.ниже вы можете найти две скрипки, по одной для каждого решения.
EDIT
кроме того, обычно нет необходимости явно загружать
ng
модуль. В обычных случаях!--6--> модель уже автоматически загружены, если вы хотите выполнить ручную загрузку кода Angular. Часть документов, упомянутых в одном из ответов, относится (неявно, к сожалению) к процедуре ручной загрузки Angular, когда вам нужно вручную создать инжектор и сообщить ему, какие модули вы хотите загрузить