Улучшить эту документациюЧто такое модуль?
Вы можете рассматривать модуль как контейнер для различных частей вашего приложения – контроллеров, сервисов, фильтров, директив и т. д.
Почему?
Большинство приложений имеют главный метод, который инициализирует и связывает разные части приложения.
Приложения Angular не имеют главного метода. Вместо этого модули декларативно указывают, как должно быть запущено приложение. Такой подход имеет несколько преимуществ:
- Декларативный процесс легче понять.
- Вы можете упаковать код в переиспользуемые модули.
- Модули могут загружаться в любом порядке (или даже параллельно), потому что модули откладывают выполнение.
- Тесты единиц должны загружать только соответствующие модули, что делает их быстрыми.
- Тесты «от края до края» могут использовать модули для переопределения конфигурации.
Основы
Мне нужно быстро. Как создать работающий модуль Hello World?
Важные моменты, на которые следует обратить внимание:
- API модуля
- Ссылка на модуль
myAppв<div ng-app="myApp">. Это то, что запускает приложение с помощью вашего модуля. - Пустой массив в
angular.module('myApp', []). Этот массив — список модулей, от которыхmyAppзависит.
Рекомендуемая настройка
Хотя приведенный выше пример прост, он не масштабируется для больших приложений. Вместо этого мы рекомендуем разбить ваше приложение на несколько модулей следующим образом:
- Модуль для каждой функции
- Модуль для каждого переиспользуемого компонента (особенно директив и фильтров)
- И модуль уровня приложения, который зависит от вышеперечисленных модулей и содержит код инициализации.
Вы можете найти руководящие принципы сообщества
стиля, которые помогут вам, когда приложение станет больше.
Вышеизложенное является предложением. Настройте его в соответствии со своими потребностями.
Загрузка модулей и зависимости
Модуль — это набор конфигурационных и исполняемых блоков, которые применяются к приложению во время процесса запуска. В самом простом виде модуль состоит из двух типов блоков:
- Конфигурационные блоки — выполняются во время регистрации и конфигурации поставщиков. В конфигурационные блоки можно вводить только поставщиков и константы. Это предотвращает случайную инициализацию сервисов до их полной конфигурации.
- Блоки выполнения — выполняются после создания инжектора и используются для запуска приложения. В блоки выполнения можно вводить только экземпляры и константы. Это предотвращает дальнейшую конфигурацию системы во время выполнения приложения.
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.4.14/docs/guide/module