Зачем использовать службы в Angular?
Я только начинаю с Angular. Читая пример сервиса в документации Google, я просто задаюсь вопросом, почему вы решили использовать службу, а не поддерживать переменные и функции прямо в контроллере?
angular.
module('MyServiceModuleDI', []).
factory('notify', function($window) {
var msgs = [];
return function(msg) {
msgs.push(msg);
if (msgs.length == 3) {
$window.alert(msgs.join("\n"));
msgs = [];
}
};
});
function myController($scope, notify) {
$scope.callNotify = function(msg) {
notify(msg);
};
}
Когда вы решили использовать услугу в этом случае?
Ответы
Ответ 1
По моему мнению, основными причинами являются:
-
Сохранять и делиться данными между контроллерами.
IE: вы создаете службу, которая извлекает данные из базы данных, если вы храните ее внутри контроллера, как только вы перейдете на другой контроллер, данные будут отброшены (если вы не сохраните их в $rootScope, но это не самый лучший способ сделать это), но если вы храните его внутри службы (сервисы - одиночные), данные будут сохраняться при изменении контроллеров.
-
Абстрактная логика доступа к данным путем создания API, который будет использоваться вашими контроллерами/директивами/службами.
Держите бизнес-логику внутри контроллеров и логику данных внутри служб.
-
DRY (не повторяйте себя).
IE: у вас есть ряд функций, которые вам нужны в разных контроллерах, без обслуживания, которое вам нужно будет повторить код в каждом контроллере с помощью сервиса вы можете создать один API для этих функций и ввести его в каждый контроллер/директиву/службу, в которой вы нуждаетесь.
Вот пример:
var myApp = angular.module('myApp',[]);
//Here is the service Users with its functions and attributes
//You can inject it in any controller, service is a singleton and its data persist between controllers
myApp.factory('Users', function () {
//data logic
//fetch data from db and populate...
var name = "John";
var surname = "Doe"
function getName() { return name; }
function getFullName() { return name + ' ' + surname; }
function setName(newName) { name = newName; }
//API
return {
getName: getName,
getFullName: getFullName,
setName: setName
}
});
//An Util service with methods I will use in different controllers
myApp.factory('Util', function () {
//a bunch of useful functions I will need everywhere
function daysInMonth (month,year) {
return new Date(year, month+1,0).getDate();
}
return {
daysInMonth: daysInMonth
};
});
//Here I am injecting the User and Util services in the controllers
myApp.controller('MyCtrl1', ['$scope', 'Users', 'Util', function ($scope, Users, Util) {
$scope.user = Users.getFullName(); //"John Doe";
Users.setName('Bittle');
//Using Util service
$scope.days = Util.daysInMonth(05,2013);
}]);
myApp.controller('MyCtrl2', ['$scope', 'Users', 'Util', function ($scope, Users, Util) {
$scope.user = Users.getFullName(); //"Bittle Doe"; //The change that took place in MyCtrl1 hhas persisted.
}]);
Ответ 2
Основываясь на моем опыте, услуги могут быть полезны в следующих сценариях:
-
Если вы хотите обмениваться информацией между двумя или несколькими контроллерами
Можно использовать $rootScope
для связи между контроллерами, но, как показывает раздел документации общих ошибок > в документации, следует избегать как можно больше, поскольку это глобальный объем. Используя сервисы, мы можем определить методы setter и getter, которые могут быть легко использованы для обмена данными между контроллерами.
-
Когда функция должна использоваться несколько раз
Допустим, что у вас есть функциональность, которая повторяется во всех шаблонах, которые у вас есть, - скажите что-то, в котором вам нужно многократно конвертировать валюту из доллара США в евро и отображать сумму для пользователя. Здесь вы можете предположить, что "сумма" - это что-то из "Закупки авиабилетов", покупка некоторых книг в Интернете - все, что связано с деньгами.
Эта функциональность будет использоваться во всех ваших шаблонах, чтобы отображать сумму всегда в евро для клиента, но в вашей базе данных/модели сумма хранится в евро.
Таким образом, вы можете создать услугу, которая конвертирует сумму от доллара США к евро. Любой контроллер может вызвать его и использовать. Теперь ваши функции теперь расположены в одном месте вместо контроллеров. Таким образом, в будущем, если вы решите внести изменения и отобразить сумму в фунтах, вам нужно сделать изменение только в одном месте, и оно будет отражено во всех используемых им контроллерах.
Есть и другие варианты использования, но только сейчас они мне приходят в голову. Наиболее часто используемым случаем, который я нахожу, используя сами службы, является точка № 1 - передача данных между контроллерами.
Ответ 3
Если вы хотите сохранить переменную в памяти (почему бы нет, например, пользовательский сеанс) во время навигации (вызываются разные частичные части с разным контроллером).
Вы должны иметь в виду:
-
Контроллеры повторно инициализируются каждый раз, когда вы их вызываете.
-
Услуги создаются только один раз и всегда доступны. Таким образом, вы можете сохранить любую необходимую информацию.
Ответ 4
Помимо преимуществ, перечисленных выше, он также помогает разделить структуру вашего приложения на независимые компоненты, что делает его более понятным и проверяемым.
Представьте, что вам нужно тестировать аналогичную функциональность в нескольких местах, а не определять/отлаживать ее в центральном месте и использовать в другом месте (несколько раз).
Ответ 5
Также напомним, что Angular-сервисы - это одноэлементные объекты (это очень важно, чтобы мы могли легко делиться ими через проект), которые создаются только один раз за время существования приложения. Они содержат методы, которые поддерживают данные в течение всего жизненного цикла приложения, то есть данные не обновляются и доступны постоянно. Основная задача службы - организовать и совместно использовать бизнес-логику, модели или данные и функции с различными компонентами приложения Angular.