Улучшить эту документациюЧто такое модуль?
Можете представить модуль как контейнер для различных частей вашего приложения – контроллеров, сервисов, фильтров, директив и т. д.
Почему?
В большинстве приложений есть главный метод, который инициализирует и связывает различные части приложения.
Приложения Angular не имеют главного метода. Вместо этого модули декларативно задают, как должно быть запущено приложение. Такой подход имеет несколько преимуществ:
- Декларативный процесс легче понять.
- Вы можете упаковать код в виде повторно используемых модулей.
- Модули могут загружаться в любом порядке (или даже параллельно), потому что модули откладывают выполнение.
- Тесты единиц должны загружать только релевантные модули, что делает их быстрыми.
- Тесты на конечном пользователе могут использовать модули для переопределения конфигурации.
Основы
Я спешу. Как мне запустить модуль «Привет, мир»?
Важные моменты:
- API модуля
- Ссылка на модуль
myAppв<div ng-app="myApp">. Это то, что запускает приложение с использованием вашего модуля. - Пустой массив в
angular.module('myApp', []). Этот массив — список модулей, от которыхmyAppзависит.
Рекомендуемая настройка
Хотя приведенный выше пример прост, он не масштабируется до больших приложений. Вместо этого рекомендуется разбить ваше приложение на несколько модулей, как это:
- Модуль для каждой функции
- Модуль для каждого повторно используемого компонента (особенно директив и фильтров)
- И модуль уровня приложения, который зависит от вышеперечисленных модулей и содержит любой код инициализации.
Мы также написали документ о том, как мы организуем большие приложения в Google.
Вышесказанное — предложение. Подстройте его под свои нужды.
Загрузка модулей и зависимости
Модуль — это набор блоков конфигурации и выполнения, которые применяются к приложению во время процесса запуска. В простейшем виде модуль состоит из набора двух видов блоков:
- Блоки конфигурации — выполняются во время регистрации и фазы конфигурации поставщиков. В блоки конфигурации можно вводить только поставщиков и константы. Это для предотвращения случайной инициализации сервисов до их полной настройки.
- Блоки выполнения — выполняются после создания инжектора и используются для запуска приложения. В блоки выполнения можно вводить только экземпляры и константы. Это для предотвращения дальнейшей настройки системы во время выполнения приложения.
angular.module('myModule', []).
config(function(injectables) { // provider-injector
// This is an example of config block.
// You can have as many of these as you want.
// You can only inject Providers (not instances)
// into config blocks.
}).
run(function(injectables) { // instance-injector
// This is an example of a run block.
// You can have as many of these as you want.
// You can only inject instances (not Providers)
// into run blocks
});
Блоки конфигурации
В модуле есть несколько удобных методов, которые эквивалентны блоку config. Например:
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', ...);
});
Блоки выполнения
Блоки выполнения — это наиболее близкое в Angular к главному методу. Блок выполнения — это код, который необходимо запустить для запуска приложения. Он выполняется после того, как все сервисы будут настроены, а инжектор будет создан. Блоки выполнения обычно содержат код, который трудно протестировать, и поэтому они должны объявляться в изолированных модулях, чтобы их можно было игнорировать в тестах единиц.
Зависимости
Модули могут перечислять другие модули в качестве своих зависимостей. Зависимость от модуля подразумевает, что необходимый модуль должен загружаться перед загрузкой требуемого модуля. Другими словами, блоки конфигурации требуемых модулей выполняются до блоков конфигурации требуемого модуля. То же самое относится к блокам выполнения. Каждый модуль может быть загружен только один раз, даже если его требуют несколько других модулей.
Асинхронная загрузка
Модули — способ управления конфигурацией $injector и не имеют ничего общего с загрузкой скриптов в виртуальную машину. Существуют существующие проекты, которые занимаются загрузкой скриптов, которые могут использоваться с Angular. Поскольку модули ничего не делают во время загрузки, их можно загрузить в виртуальную машину в любом порядке, и поэтому загрузчики скриптов могут воспользоваться этим свойством и распараллелить процесс загрузки.
Создание и получение
Будьте осторожны, использование 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–2017 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.2.32/docs/guide/module