Улучшить эту документациюСервисы
Сервисы AngularJS — это заменяемые объекты, которые связаны с помощью ввода зависимостей (DI). Вы можете использовать сервисы для организации и совместного использования кода в приложении.
Сервисы AngularJS:
- Лениво инициализируются — AngularJS инициализирует сервис только тогда, когда компонент приложения зависит от него.
- Одиночные экземпляры — Каждый компонент, зависящий от сервиса, получает ссылку на единственный экземпляр, сгенерированный фабрикой сервиса.
AngularJS предлагает несколько полезных сервисов (например, $http), но для большинства приложений вам также потребуется создать свой собственный.
$ (например, $http). Использование сервиса
Чтобы использовать сервис AngularJS, добавьте его в качестве зависимости для компонента (контроллера, сервиса, фильтра или директивы), который зависит от сервиса. Подсистема ввода зависимостей AngularJS позаботится обо всём остальном.
Создание сервисов
Разработчики приложений могут определять свои собственные сервисы, регистрируя имя сервиса и функцию-фабрику сервиса в модуле AngularJS.
Функция-фабрика сервиса генерирует единственный объект или функцию, представляющую сервис для остальной части приложения. Объект или функция, возвращаемые сервисом, вводятся в любой компонент (контроллер, сервис, фильтр или директива), который указывает зависимость от сервиса.
Регистрация сервисов
Сервисы регистрируются в модулях через API модуля. Обычно вы используете API фабрики модуля, чтобы зарегистрировать сервис:
var myModule = angular.module('myModule', []);
myModule.factory('serviceId', function() {
var shinyNewServiceInstance;
// factory function body that constructs shinyNewServiceInstance
return shinyNewServiceInstance;
});
Обратите внимание, что вы регистрируете не экземпляр сервиса, а функцию-фабрику, которая создаст этот экземпляр при вызове.
Зависимости
Сервисы могут иметь свои собственные зависимости. Так же, как вы объявляете зависимости в контроллере, вы объявляете зависимости, указав их в сигнатуре функции-фабрики сервиса.
Дополнительную информацию о зависимостях см. в документации по вводу зависимостей.
Ниже представлен пример модуля с двумя сервисами, каждый из которых имеет различные зависимости:
var batchModule = angular.module('batchModule', []);
/**
* The `batchLog` service allows for messages to be queued in memory and flushed
* to the console.log every 50 seconds.
*
* @param {*} message Message to be logged.
*/
batchModule.factory('batchLog', ['$interval', '$log', function($interval, $log) {
var messageQueue = [];
function log() {
if (messageQueue.length) {
$log.log('batchLog messages: ', messageQueue);
messageQueue = [];
}
}
// start periodic checking
$interval(log, 50000);
return function(message) {
messageQueue.push(message);
}
}]);
/**
* `routeTemplateMonitor` monitors each `$route` change and logs the current
* template via the `batchLog` service.
*/
batchModule.factory('routeTemplateMonitor', ['$route', 'batchLog', '$rootScope',
function($route, batchLog, $rootScope) {
return {
startMonitoring: function() {
$rootScope.$on('$routeChangeSuccess', function() {
batchLog($route.current ? $route.current.template : null);
});
}
};
}]);
В примере обратите внимание на:
- Сервис
batchLogзависит от встроенных сервисов$intervalи$log. - Сервис
routeTemplateMonitorзависит от встроенного сервиса$routeи нашего настраиваемого сервисаbatchLog. - Оба сервиса используют обозначение массива для объявления зависимостей.
- Порядок идентификаторов в массиве соответствует порядку имен аргументов в функции-фабрике.
Регистрация сервиса с помощью $provide
Вы также можете регистрировать сервисы через сервис $provide внутри функции config модуля:
angular.module('myModule', []).config(['$provide', function($provide) {
$provide.factory('serviceId', function() {
var shinyNewServiceInstance;
// factory function body that constructs shinyNewServiceInstance
return shinyNewServiceInstance;
});
}]);
Этот метод часто используется в модульных тестах для имитации зависимостей сервиса.
Модульное тестирование
Ниже представлен модульный тест для сервиса notify из примера Создание сервисов AngularJS выше. В примере модульного теста используется шпион Jasmine (модель) вместо реального всплывающего окна браузера alert.
var mock, notify;
beforeEach(module('myServiceModule'));
beforeEach(function() {
mock = {alert: jasmine.createSpy()};
module(function($provide) {
$provide.value('$window', mock);
});
inject(function($injector) {
notify = $injector.get('notify');
});
});
it('should not alert first two notifications', function() {
notify('one');
notify('two');
expect(mock.alert).not.toHaveBeenCalled();
});
it('should alert all after third notification', function() {
notify('one');
notify('two');
notify('three');
expect(mock.alert).toHaveBeenCalledWith("one\ntwo\nthree");
});
it('should clear messages after alert', function() {
notify('one');
notify('two');
notify('third');
notify('more');
notify('two');
notify('third');
expect(mock.alert.calls.count()).toEqual(2);
expect(mock.alert.calls.mostRecent().args).toEqual(["more\ntwo\nthird"]);
});
Связанные темы
Связанный API
© 2010–2020 Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
https://code.angularjs.org/1.8.2/docs/guide/services