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