AngularJS: фабрика и сервис?
РЕДАКТИРОВАТЬ Январь 2016: Поскольку это все еще привлекает внимание. С тех пор, как я спросил об этом, я завершил несколько проектов AngularJS, и для тех, кого я в основном использовал factory
, построил объект и вернул объект в конце. Мои утверждения ниже все еще верны, как бы то ни было.
РЕДАКТИРОВАТЬ: я думаю, что я, наконец, понимаю главное различие между ними, и у меня есть пример кода для демонстрации. Я также думаю, что этот вопрос отличается от предложенного дубликата. Дубликат говорит, что сервис не является инстанцируемым, но если вы настроите его, как я продемонстрировал ниже, это действительно так. Сервис может быть настроен так же, как на заводе. Я также предоставлю код, показывающий, где на заводе происходит сбой в обслуживании, что, похоже, не дает никакой другой ответ.
Если я настрою VaderService так (например, как сервис):
var module = angular.module('MyApp.services', []);
module.service('VaderService', function() {
this.speak = function (name) {
return 'Join the dark side ' + name;
}
});
Тогда в моем контроллере я могу сделать это:
module.controller('StarWarsController', function($scope, VaderService) {
$scope.luke = VaderService.speak('luke');
});
С помощью сервиса создается экземпляр VaderService, введенный в контроллер, поэтому я могу просто вызвать VaderService.speak, однако, если я изменю VaderService на module.factory, код в контроллере больше не будет работать, и в этом главное отличие, С фабрикой VaderService, внедренный в контроллер, не создается, поэтому вам нужно возвращать объект при настройке фабрики (см. Мой пример в вопросе).
Тем не менее, вы можете настроить сервис точно так же, как вы можете настроить фабрику (в IE она возвращает объект), и сервис ведет себя точно так же, как фабрика
Учитывая эту информацию, я не вижу причин использовать фабрику над обслуживанием, обслуживание может сделать все, что может фабрика, и даже больше.
Оригинальный вопрос ниже.
Я знаю, что об этом спрашивали много раз, но я действительно не вижу никакой функциональной разницы между фабриками и службами. Я читал этот учебник: http://blogs.clevertech.biz/startupblog/angularjs-factory-service-provider
И это, кажется, дает достаточно хорошее объяснение, однако я настроил свое приложение следующим образом:
index.html
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<script src="lib/angular/angular.js"></script>
<script type="text/javascript" src="js/controllers.js"></script>
<script type="text/javascript" src="js/VaderService.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</head>
<body ng-app="MyApp">
<table ng-controller="StarWarsController">
<tbody>
<tr><td>{{luke}}</td></tr>
</tbody>
</table>
</body>
</html>
app.js:
angular.module('MyApp', [
'MyApp.services',
'MyApp.controllers'
]);
controllers.js:
var module = angular.module('MyApp.controllers', []);
module.controller('StarWarsController', function($scope, VaderService) {
var luke = new VaderService('luke');
$scope.luke = luke.speak();
});
VaderService.js
var module = angular.module('MyApp.services', []);
module.factory('VaderService', function() {
var VaderClass = function(padawan) {
this.name = padawan;
this.speak = function () {
return 'Join the dark side ' + this.name;
}
}
return VaderClass;
});
Затем, когда я загружаю index.html, я вижу "Присоединяйся к темной стороне, Люк", отлично. Точно так, как и ожидалось. Однако, если я изменю VaderService.js на этот (обратите внимание на module.service вместо module.factory):
var module = angular.module('MyApp.services', []);
module.service('VaderService', function() {
var VaderClass = function(padawan) {
this.name = padawan;
this.speak = function () {
return 'Join the dark side ' + this.name;
}
}
return VaderClass;
});
Затем перезагрузите index.html (я удостоверился, что очистил кеш и сделал полную перезагрузку). Он работает точно так же, как и с module.factory. Так в чем же реальная функциональная разница между этими двумя?
4 ответа
Сервис против Фабрики
Разница между фабрикой и обслуживанием так же, как разница между функцией и объектом
Фабрика Провайдер
Дает нам возвращаемое значение функции т.е. Вы просто создаете объект, добавляете к нему свойства, а затем возвращаете тот же объект. Когда вы передаете этот сервис в свой контроллер, эти свойства объекта теперь будут доступны в этом контроллере через вашу фабрику. (Гипотетический сценарий)
Синглтон и будет создан только один раз
Многоразовые компоненты
Фабрика - отличный способ общения между контроллерами, например, обмен данными.
Можно использовать другие зависимости
Обычно используется, когда экземпляр службы требует сложной логики создания
Не может быть введен в
.config()
функция.Используется для неконфигурируемых сервисов
Если вы используете объект, вы можете использовать поставщика фабрики.
Синтаксис:
module.factory('factoryName', function);
Поставщик услуг
Дает нам экземпляр функции (объекта)- вы просто создаете экземпляр с ключевым словом "new", и вы добавляете свойства к "this", и сервис возвращает "this". Когда вы передаете сервис в свой контроллер, эти свойства "Это" теперь будет доступно на этом контроллере через ваш сервис. (Гипотетический сценарий)
Синглтон и будет создан только один раз
Многоразовые компоненты
Сервисы используются для связи между контроллерами для обмена данными
Вы можете добавить свойства и функции к объекту службы, используя
this
ключевое словоЗависимости вводятся как аргументы конструктора
Используется для простой логики создания
Не может быть введен в
.config()
функция.Если вы используете класс, вы можете использовать поставщика услуг
Синтаксис:
module.service(‘serviceName’, function);
В приведенном ниже примере у меня есть определение MyService
а также MyFactory
, Обратите внимание, как в .service
Я создал сервисные методы, используя this.methodname.
В .factory
Я создал фабричный объект и назначил ему методы.
AngularJS.service
module.service('MyService', function() {
this.method1 = function() {
//..method1 logic
}
this.method2 = function() {
//..method2 logic
}
});
AngularJS.factory
module.factory('MyFactory', function() {
var factory = {};
factory.method1 = function() {
//..method1 logic
}
factory.method2 = function() {
//..method2 logic
}
return factory;
});
Также посмотрите на эти красивые вещи
Смущен сервисом против фабрики
Factory
а также Service
это просто обертка provider
,
завод
Factory
может вернуть все, что может быть class(constructor function)
, instance of class
, string
, number
или же boolean
, Если вы вернете constructor
функция, вы можете создать экземпляр в вашем контроллере.
myApp.factory('myFactory', function () {
// any logic here..
// Return any thing. Here it is object
return {
name: 'Joe'
}
}
обслуживание
Сервис не должен ничего возвращать. Но вы должны назначить все в this
переменная. Потому что служба создаст экземпляр по умолчанию и будет использовать его как базовый объект.
myApp.service('myService', function () {
// any logic here..
this.name = 'Joe';
}
Фактический код angularjs за сервисом
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}
Это просто обертка вокруг factory
, Если вы вернете что-то из service
то будет вести себя как Factory
,
IMPORTANT
: Возвращаемый результат от Factory и Service будет кешем и будет возвращен для всех контроллеров.
Когда я должен их использовать?
Factory
в большинстве случаев предпочтительнее. Может использоваться, когда у вас есть constructor
функция, которая должна быть реализована в разных контроллерах.
Service
это своего рода Singleton
Объект. Возврат Объекта из Сервиса будет одинаковым для всех контроллеров. Его можно использовать, когда вы хотите иметь один объект для всего приложения. Например: аутентифицированные данные пользователя.
Для дальнейшего понимания прочитайте
http://iffycan.blogspot.in/2013/05/angular-service-or-factory.html
http://viralpatel.net/blogs/angularjs-service-factory-tutorial/
- Если вы используете сервис, вы получите экземпляр функции (ключевое слово "this").
- Если вы используете фабрику, вы получите возвращаемое значение, вызвав ссылку на функцию (оператор возврата в фабрике)
Фабрика и Сервис - наиболее часто используемые рецепты. Единственное различие между ними заключается в том, что рецепт Service лучше работает для объектов пользовательского типа, тогда как Factory может создавать примитивы и функции JavaScript.
$ предоставить услугу
Технически это одно и то же, на самом деле это разные обозначения использования provider
функция $provide
сервис.
- Если вы используете класс: вы можете использовать служебную нотацию.
- Если вы используете объект: вы можете использовать фабричную нотацию.
Единственная разница между service
и factory
примечание, что сервис является новым, а завод нет. Но для всего остального они оба выглядят, пахнут и ведут себя одинаково. Опять же, это просто сокращение для функции $provide.provider.
// Factory
angular.module('myApp').factory('myFactory', function() {
var _myPrivateValue = 123;
return {
privateValue: function() { return _myPrivateValue; }
};
});
// Service
function MyService() {
this._myPrivateValue = 123;
}
MyService.prototype.privateValue = function() {
return this._myPrivateValue;
};
angular.module('myApp').service('MyService', MyService);