Пожалуйста, несите меня здесь. Я знаю, что есть и другие ответы, такие как: AngularJS: Сервис против провайдера vs factory
Однако я все еще не могу понять, когда вы будете использовать службу через factory.
Из того, что я могу сказать, factory обычно используется для создания "общих" функций, которые могут вызываться несколькими контроллерами: Создание общих функций контроллера
Документы Angular, похоже, предпочитают factory через службу. Они даже ссылаются на "сервис", когда они используют factory, что еще более запутанно! http://docs.angularjs.org/guide/dev_guide.services.creating_services
Итак, когда вы будете использовать сервис?
Есть ли что-то, что возможно или намного проще с обслуживанием?
Есть ли что-то другое, что происходит за кулисами? Различия в производительности/памяти?
Вот пример. Помимо метода декларирования, они кажутся одинаковыми, и я не могу понять, почему я делаю одно против другого. http://jsfiddle.net/uEpkE/
Обновление: От ответа Томаса, похоже, подразумевается, что служба для более простой логики и factory для более сложной логики с частными методами, поэтому я обновил код скрипки ниже, и кажется, что оба могут поддерживать частные функции?
myApp.factory('fooFactory', function() {
var fooVar;
var addHi = function(foo){ fooVar = 'Hi '+foo; }
return {
setFoobar: function(foo){
addHi(foo);
},
getFoobar:function(){
return fooVar;
}
};
});
myApp.service('fooService', function() {
var fooVar;
var addHi = function(foo){ fooVar = 'Hi '+foo;}
this.setFoobar = function(foo){
addHi(foo);
}
this.getFoobar = function(){
return fooVar;
}
});
function MyCtrl($scope, fooService, fooFactory) {
fooFactory.setFoobar("fooFactory");
fooService.setFoobar("fooService");
//foobars = "Hi fooFactory, Hi fooService"
$scope.foobars = [
fooFactory.getFoobar(),
fooService.getFoobar()
];
}
У вас здесь разные вещи:
Сначала:
this
"
ключевое слово).ref: angular.service vs angular.factory
Второй:
Имейте в виду, что все провайдеры в AngularJS (стоимость, постоянная, услуги, фабрики) являются синглтонами!
Третий:
Использование одного или другого (службы или factory) относится к стилю кода. Но общий способ в AngularJS состоит в использовании factory.
Почему?
Потому что "Метод factory является наиболее распространенным способом получения объектов в системе встраивания зависимостей AngularJS. Он очень гибкий и может содержать сложную логику создания. Поскольку фабрики являются регулярными функциями, мы можем также использовать новую лексическую область для моделирования переменных "private". Это очень полезно, поскольку мы можем скрыть детали реализации данной службы".
(ref: http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821).
Сервис: может быть полезно для совместного использования служебных функций, которые полезны для вызова, просто добавляя ()
к ссылке с введенной функцией. Также может выполняться с injectedArg.call(this)
или аналогичным.
Factory: Может быть полезно вернуть функцию класса, которая затем может быть новой для создания экземпляров.
Итак, используйте factory, когда у вас сложная логика в вашей службе, а вы не хотите раскрывать эту сложность.
В других случаях , если вы хотите вернуть экземпляр службы, просто используйте службу.
Но вы увидите со временем, что будете использовать factory в 80% случаев, я думаю.
Подробнее: http://blog.manishchhabra.com/2013/09/angularjs-service-vs-factory-with-example/
ОБНОВЛЕНИЕ:
Отличный пост здесь: http://iffycan.blogspot.com.ar/2013/05/angular-service-or-factory.html
"Если вы хотите, чтобы ваша функция вызывалась как обычная функция, используйте factory. Если вы хотите, чтобы ваша функция была создана с новым оператор, используйте сервис. Если вы не знаете разницы, используйте factory."
ОБНОВЛЕНИЕ:
Команда AngularJS выполняет свою работу и дает объяснение: http://docs.angularjs.org/guide/providers
И с этой страницы:
"Factory и Service являются наиболее часто используемыми рецептами. Единственное различие между ними заключается в том, что рецепт службы лучше работает для объектов пользовательского типа, а factory может создавать примитивы и функции JavaScript.
allernhwkim изначально отправил ответ по этому вопросу, ссылаясь на его блог, однако модератор удалил его. Это единственное сообщение, которое я нашел, который не просто говорит вам, как делать то же самое с сервисом, провайдером и factory, но также сообщает вам, что вы можете делать с провайдером, которого вы не можете с помощью factory и с помощью factory, который вы не можете использовать со службой.
Непосредственно из своего блога:
app.service('CarService', function() {
this.dealer="Bad";
this.numCylinder = 4;
});
app.factory('CarFactory', function() {
return function(numCylinder) {
this.dealer="Bad";
this.numCylinder = numCylinder
};
});
app.provider('CarProvider', function() {
this.dealerName = 'Bad';
this.$get = function() {
return function(numCylinder) {
this.numCylinder = numCylinder;
this.dealer = this.dealerName;
}
};
this.setDealerName = function(str) {
this.dealerName = str;
}
});
Это показывает, как CarService всегда будет производить автомобиль с 4 цилиндрами, вы не сможете его изменить для отдельных автомобилей. В то время как CarFactory возвращает функцию, поэтому вы можете сделать new CarFactory
в своем контроллере, пройдя несколько цилиндров, характерных для этого автомобиля. Вы не можете сделать new CarService
, потому что CarService - это объект, а не функция.
Причина, по которой фабрики работают не так:
app.factory('CarFactory', function(numCylinder) {
this.dealer="Bad";
this.numCylinder = numCylinder
});
И автоматически возвращайте функцию для создания экземпляра, потому что тогда вы не можете этого сделать (добавьте вещи в прототип /etc ):
app.factory('CarFactory', function() {
function Car(numCylinder) {
this.dealer="Bad";
this.numCylinder = numCylinder
};
Car.prototype.breakCylinder = function() {
this.numCylinder -= 1;
};
return Car;
});
Посмотрите, как буквально factory создает автомобиль.
Вывод из его блога довольно хорош:
В заключение,
--------------------------------------------------- | Type | Singleton| Instantiable | Configurable| --------------------------------------------------- | Factory | Yes | No | No | --------------------------------------------------- | Service | Yes | Yes | No | --------------------------------------------------- | Provider| Yes | Yes | Yes | ---------------------------------------------------
Используйте factory, когда вам нужен простой объект, такой как Hash, для example {foo; 1, bar: 2} Его легко закодировать, но вы не можете создать экземпляр он.
Используйте службу, когда вам нужно создать экземпляр объекта, т.е. новый Клиент(), новый комментарий() и т.д.
Используйте Provider, когда вам нужно его настроить. то есть тестовый URL, URL-адрес QA, производственный адрес.
Если вы обнаружите, что просто возвращаете объект в factory, вы, вероятно, должны использовать службу.
Не делайте этого:
app.factory('CarFactory', function() {
return {
numCylinder: 4
};
});
Используйте сервис вместо:
app.service('CarService', function() {
this.numCylinder = 4;
});
Концепция для всех этих поставщиков намного проще, чем первоначально. Если вы проанализируете поставщика и вытащите разные части, он станет очень понятным.
Проще говоря, каждый из этих поставщиков является специализированной версией другой, в следующем порядке: provider
> factory
> value
/constant
/service
.
До тех пор, пока провайдер делает все возможное, вы можете использовать провайдера дальше по цепочке, что приведет к сокращению количества кода. Если он не выполняет то, что вы хотите, вы можете подняться по цепочке, и вам просто нужно написать больше кода.
Это изображение иллюстрирует, что я имею в виду. На этом изображении вы увидите код для провайдера, с выделенными фрагментами, показывающими, какие части поставщика могут использоваться для создания factory, значения и т.д. вместо.
Для получения более подробной информации и примеров из сообщения в блоге, где я получил изображение, перейдите по ссылке: http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
Оба factory и службы приводят к одноточечным объектам, которые могут быть настроены поставщиками и введены в контроллеры и блоки запуска. С точки зрения инъектора, нет никакой разницы, был ли объект получен из factory или службы.
Итак, когда использовать factory и когда использовать услугу? Это сводится к вашим предпочтениям в кодировании, и ничего больше. Если вам нравится модульный шаблон JS, перейдите к factory. Если вам нравится стиль конструктора ( "класс" ), перейдите к службе. Обратите внимание, что оба стиля поддерживают частные члены.
Преимущество службы может заключаться в том, что она более интуитивно понятна с точки зрения ООП: создайте "класс" и совместно с провайдером повторно используйте один и тот же код между модулями и измените поведение объектов-экземпляров просто путем предоставления различных параметров конструктору в блоке конфигурации.
Даже когда говорят, что все сервисы и заводы однотонные, я не согласен с этим на 100 процентов. Я бы сказал, что фабрики не одиночные, и это точка моего ответа. Я бы действительно подумал о имени, которое определяет каждый компонент (Service/ Factory), я имею в виду:
A factory, потому что он не является одиночным, вы можете создавать столько, сколько хотите, когда вы вводите, поэтому он работает как объект factory. Вы можете создать factory объекта вашего домена и работать более комфортно с этими объектами, которые могут быть похожими на объект вашей модели. Когда вы извлекаете несколько объектов, вы можете отображать их в этих объектах, и они могут действовать как другой слой между DDBB и моделью AngularJs. Вы можете добавлять методы к объектам, чтобы вы ориентировались на объекты немного больше вашего приложения AngularJs.
Между тем служба - это одиночный элемент, поэтому мы можем создать только один вид, возможно, не создадим, но у нас есть только один экземпляр, когда мы вводим в контроллер, поэтому служба больше похожа на общая служба (вызовы отдыха, функциональность..) для контроллеров.
Концептуально вы можете думать, что службы предоставляют услугу, фабрики могут создавать несколько экземпляров (объектов) класса
Нет ничего, что Factory не может сделать или лучше по сравнению с Сервисом. И наоборот. Factory просто кажется более популярным. Причиной этого является его удобство в обращении с частными/общественными членами. Служба будет более неуклюжей в этом отношении. При кодировании службы вы, как правило, делаете своих членов объектов общедоступными с помощью ключевого слова "this" и можете внезапно обнаружить, что эти публичные элементы не видны частным методам (т.е. Внутренним функциям).
var Service = function(){
//public
this.age = 13;
//private
function getAge(){
return this.age; //private does not see public
}
console.log("age: " + getAge());
};
var s = new Service(); //prints 'age: undefined'
Angular использует ключевое слово "новое" для создания службы для вас, поэтому экземпляр Angular переходит к контроллеру, будет иметь тот же недостаток. Конечно, вы можете преодолеть проблему, используя это/это:
var Service = function(){
var that = this;
//public
this.age = 13;
//private
function getAge(){
return that.age;
}
console.log("age: " + getAge());
};
var s = new Service();// prints 'age: 13'
Но с большой константой Сервиса это сделает код плохо читаемым. Более того, прототипы службы не будут видеть частных членов - для них будет доступна только публика:
var Service = function(){
var name = "George";
};
Service.prototype.getName = function(){
return this.name; //will not see a private member
};
var s = new Service();
console.log("name: " + s.getName());//prints 'name: undefined'
Подводя итог, использование Factory более удобно. Поскольку Factory не имеет этих недостатков. Я бы порекомендовал использовать его по умолчанию.
myapp.service(...)
полностью отсутствует. Где должен вызываться new Service()
, в сервисной функции или в месте, где вводится Service. Третий листинг просто невозможен в контексте myapp.service ('Service', function() {...})
.
Можно использовать способ: создать объект или j ust для доступа к функциям из
Вы можете создать новый объект из службы
app.service('carservice', function() {
this.model = function(){
this.name = Math.random(22222);
this.price = 1000;
this.colour = 'green';
this.manufacturer = 'bmw';
}
});
.controller('carcontroller', function ($scope,carservice) {
$scope = new carservice.model();
})
Примечание:
Вы можете создать новый объект из factory
app.factory('carfactory', function() {
var model = function(){
this.name = Math.random(22222);
this.price = 1000;
this.colour = 'green';
this.manufacturer = 'bmw';
}
return model;
});
.controller('carcontroller', function ($scope,carfactory) {
$scope = new carfactory();
})
Примечание:
Создать сервис для простого доступа к простым функциям
app.service('carservice', function () {
this.createCar = function () {
console.log('createCar');
};
this.deleteCar = function () {
console.log('deleteCar');
};
});
.controller('MyService', function ($scope,carservice) {
carservice.createCar()
})
Создать factory для простого доступа к простым функциям
app.factory('carfactory', function () {
var obj = {}
obj.createCar = function () {
console.log('createCar');
};
obj.deleteCar = function () {
console.log('deleteCar');
};
});
.controller('MyService', function ($scope,carfactory) {
carfactory.createCar()
})
Заключение:
Услуги
Синтаксис: module.service('serviceName', function); Результат. При объявлении serviceName в качестве аргумента для инъекции вам будет предоставлен фактический справочник функций, переданный модулю service.service.
Использование. Может быть полезно для совместного использования служебных функций, которые полезны для вызова, просто добавляя() к ссылке с введенной функцией. Также можно запустить с помощью injectedArg.call(this) или аналогичного.
Заводы
Синтаксис: module.factory('factoryName', function);
Результат: при объявлении имени factoryName в качестве аргумента для инъекции вам будет предоставлено значение, возвращаемое вызовом ссылки на функцию, переданной модулю .factory.
Использование. Может оказаться полезным для возврата функции класса, которая затем может быть создана для создания экземпляров.
Провайдеры
Синтаксис: module.provider('providerName', function);
Результат. При объявлении имени поставщика в качестве аргумента для инъекции вам будет предоставлено значение, возвращаемое при вызове метода $get ссылки на функцию, переданной модулю .provider.
Использование. Может оказаться полезным для возврата функции класса, которая затем может быть создана для создания экземпляров, но перед введением требуется какая-то конфигурация. Возможно, полезно для классов, которые многократно используются для разных проектов? Еще один туманный на этом.