Улучшить эту документациюСервисы
Сервисы Angular — это заменяемые объекты, которые связаны друг с другом с помощью ввода зависимостей (DI). Вы можете использовать сервисы для организации и совместного использования кода по всему приложению.
Сервисы Angular:
- Инициализируются лениво — Angular инициализирует сервис только тогда, когда компонент приложения зависит от него.
- Являются синглтонами — каждый компонент, зависящий от сервиса, получает ссылку на единственный экземпляр, созданный фабрикой сервиса.
Angular предлагает несколько полезных сервисов (например, $http), но для большинства приложений вам также потребуется создать свой собственный.
$ (например, $http). Использование сервиса
Чтобы использовать сервис Angular, добавьте его в качестве зависимости для компонента (контроллера, сервиса, фильтра или директивы), который зависит от сервиса. Система ввода зависимостей Angular позаботится о остальном.
Создание сервисов
Разработчики приложений могут определять свои собственные сервисы, регистрируя имя сервиса и функцию-фабрику сервиса в модуле Angular.
Функция-фабрика сервиса генерирует единственный объект или функцию, представляющий сервис для остальной части приложения. Объект или функция, возвращаемые сервисом, вводятся в любой компонент (контроллер, сервис, фильтр или директиву), который указывает зависимость от сервиса.
Регистрация сервисов
Сервисы регистрируются в модулях через 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 из примера Создание сервисов Angular выше. В примере модульного теста используется шпион 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.callCount).toEqual(2);
expect(mock.alert.mostRecentCall.args).toEqual(["more\ntwo\nthird"]);
});
Связанные темы
Связанный API
© 2010–2017 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.4.14/docs/guide/services