Улучшить эту документациюМодули
Что такое модуль?
Модуль можно рассматривать как контейнер для различных частей приложения — контроллеров, сервисов, фильтров, директив и т. д.
Почему?
Большинство приложений имеют главный метод, который инициализирует и связывает различные части приложения.
Приложения AngularJS не имеют главного метода. Вместо этого модули декларативно определяют, как приложение должно быть запущенно. Этот подход имеет несколько преимуществ:
- Декларативный процесс проще понять.
- Вы можете упаковать код в качестве повторно используемых модулей.
- Модули можно загружать в любом порядке (или даже параллельно), так как модули откладывают выполнение.
- Тесты единиц должны загружать только соответствующие модули, что делает их быстрыми.
- Конечные тесты могут использовать модули для перезаписи конфигурации.
Основы
Мне нужно быстро. Как создать работающий модуль "Hello World"?
Важно обратить внимание на:
- API модуля
- Ссылка на
myAppмодуль в<div ng-app="myApp">. Именно это запускает приложение с использованием вашего модуля. - Пустой массив в
angular.module('myApp', []). Этот массив представляет список модулей, от которыхmyAppзависит.
Рекомендуемая настройка
Хотя приведенный выше пример прост, он не масштабируется для крупных приложений. Вместо этого рекомендуется разбить ваше приложение на несколько модулей, например:
- Модуль для каждой функции
- Модуль для каждого повторно используемого компонента (особенно директив и фильтров)
- И модуль уровня приложения, который зависит от вышеперечисленных модулей и содержит код инициализации.
Вы можете найти руководящие принципы сообщества стиля, которые помогут вам, когда приложение разрастётся.
Вышеизложенное — предложение. Подстройте его под свои потребности.
Загрузка модуля
Модуль — это набор поставщиков, сервисов, директив и, необязательно, блоков конфигурации и выполнения, которые применяются к приложению во время процесса запуска.
API модуля описывает все доступные методы и способы их использования.
См. Использование инъекции зависимостей, чтобы узнать, какие зависимости могут быть инъецированы в каждый метод.
Зависимости и порядок выполнения
Модули могут перечислять другие модули в качестве своих зависимостей. Зависимость от модуля подразумевает, что требуемый модуль будет загружен перед загрузкой модуля, который его требует.
В одном модуле порядок выполнения следующий:
-
Функции поставщика выполняются, поэтому они и определяемые ими сервисы могут быть доступны для $injector.
-
После этого выполняются блоки конфигурации (функции конфигурации). Это означает, что блоки конфигурации необходимых модулей выполняются до блоков конфигурации любого модуля, который их требует.
Это продолжается до тех пор, пока все зависимости модуля не будут разрешены.
Затем блоки run, собранные из каждого модуля, выполняются в порядке необходимости.
Примечание: каждый модуль загружается только один раз, даже если его требуют несколько других модулей. Примечание: функция фабрики для "значений" и "сервисов" вызывается лениво, когда значение/сервис вводится впервые.
Регистрация в блоке конфигурации
Хотя рекомендуется регистрировать инъектируемые объекты непосредственно с помощью API модуля, также можно регистрировать сервисы, директивы и т. д., вводя $provide или отдельных поставщиков сервисов в функцию конфигурации:
angular.module('myModule', []).
value('a', 123).
factory('a', function() { return 123; }).
directive('directiveName', ...).
filter('filterName', ...);
// is same as
angular.module('myModule', []).
config(function($provide, $compileProvider, $filterProvider) {
$provide.value('a', 123);
$provide.factory('a', function() { return 123; });
$compileProvider.directive('directiveName', ...);
$filterProvider.register('filterName', ...);
});
Блоки run
Блоки run — это ближайшее, что есть в AngularJS к главному методу. Блок run — это код, который необходимо выполнить, чтобы запустить приложение. Он выполняется после того, как все сервисы будут сконфигурированы и инжектор будет создан. Блоки run обычно содержат код, который трудно протестировать, и поэтому должны быть объявлены в изолированных модулях, чтобы они могли быть проигнорированы в тестах единиц.
Асинхронная загрузка
Модули — это способ управления конфигурацией $injector и не имеют ничего общего с загрузкой скриптов в виртуальную машину. Существуют существующие проекты, которые занимаются загрузкой скриптов, которые могут использоваться с AngularJS. Поскольку модули ничего не делают во время загрузки, их можно загружать в виртуальную машину в любом порядке, а значит, загрузчики скриптов могут воспользоваться этим свойством и распараллелить процесс загрузки.
Создание против извлечения
Обратите внимание, что использование angular.module('myModule', []) создаст модуль myModule и перезапишет любой существующий модуль с именем myModule. Используйте angular.module('myModule') для получения существующего модуля.
var myModule = angular.module('myModule', []);
// add some directives and services
myModule.service('myService', ...);
myModule.directive('myDirective', ...);
// overwrites both myService and myDirective by creating a new module
var myModule = angular.module('myModule', []);
// throws an error because myOtherModule has yet to be defined
var myModule = angular.module('myOtherModule');
Тестирование единиц
Тест единицы — это способ инициализации подмножества приложения для применения к нему стимулов. Малые, структурированные модули помогают поддерживать тесты единиц лаконичными и целенаправленными.
Во всех этих примерах мы будем предполагать такое определение модуля:
angular.module('greetMod', []).
factory('alert', function($window) {
return function(text) {
$window.alert(text);
}
}).
value('salutation', 'Hello').
factory('greet', function(alert, salutation) {
return function(name) {
alert(salutation + ' ' + name + '!');
}
});
Давайте напишем некоторые тесты, чтобы показать, как перезаписывать конфигурацию в тестах.
describe('myApp', function() {
// load application module (`greetMod`) then load a special
// test module which overrides `$window` with a mock version,
// so that calling `window.alert()` will not block the test
// runner with a real alert box.
beforeEach(module('greetMod', function($provide) {
$provide.value('$window', {
alert: jasmine.createSpy('alert')
});
}));
// inject() will create the injector and inject the `greet` and
// `$window` into the tests.
it('should alert on $window', inject(function(greet, $window) {
greet('World');
expect($window.alert).toHaveBeenCalledWith('Hello World!');
}));
// this is another way of overriding configuration in the
// tests using inline `module` and `inject` methods.
it('should alert using the alert service', function() {
var alertSpy = jasmine.createSpy('alert');
module(function($provide) {
$provide.value('alert', alertSpy);
});
inject(function(greet) {
greet('World');
expect(alertSpy).toHaveBeenCalledWith('Hello World!');
});
});
});
© 2010–2020 Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
https://code.angularjs.org/1.8.2/docs/guide/module