AngularJS: Когда использовать службу вместо factory
Пожалуйста, несите меня здесь. Я знаю, что есть и другие ответы, такие как: 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()
];
}
Ответы
Ответ 1
объяснение
Здесь есть разные вещи:
Первый:
- Если вы используете сервис, вы получите экземпляр функции (ключевое слово "
this
"). - Если вы используете фабрику, вы получите возвращаемое значение, вызвав ссылку на функцию (оператор возврата в фабрике).
ссылка: angular.service против angular.factory
Во- вторых:
Имейте в виду, что все провайдеры в AngularJS (стоимость, константа, услуги, фабрики) являются одиночками!
В третьих:
Использование одного или другого (сервис или фабрика) о стиле кода. Но в AngularJS распространенным способом является использование фабрики.
Зачем?
Поскольку "фабричный метод является наиболее распространенным способом получения объектов в систему внедрения зависимостей AngularJS. Он очень гибкий и может содержать сложную логику создания. Поскольку фабрики являются регулярными функциями, мы также можем воспользоваться новой лексической областью для моделирования" частного "Переменные. Это очень полезно, поскольку мы можем скрыть детали реализации данного сервиса."
(ссылка: http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821).
использование
Служба: может быть полезна для совместного использования служебных функций, которые полезно вызывать, просто добавляя ()
к введенной ссылке на функцию. Также может быть запущен с помощью injectedArg.call(this)
или аналогичным.
Фабрика: Может быть полезно для возврата функции класса, которая затем может быть новой для создания экземпляров.
Поэтому используйте фабрику, когда у вас есть сложная логика в вашем сервисе, и вы не хотите раскрывать эту сложность.
В других случаях, если вы хотите вернуть экземпляр службы, просто используйте службу.
Но я думаю, что со временем вы увидите, что будете использовать фабрику в 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
"Если вы хотите, чтобы ваша функция вызывалась как обычная функция, используйте фабрику. Если вы хотите, чтобы ваша функция создавалась с помощью нового оператора, используйте сервис. Если вы не знаете разницу, используйте фабрику".
ОБНОВИТЬ :
Команда AngularJS выполняет свою работу и дает объяснения: http://docs.angularjs.org/guide/providers
И с этой страницы:
"Фабрика и Сервис - наиболее часто используемые рецепты. Единственное отличие между ними состоит в том, что Сервисный рецепт работает лучше для объектов пользовательского типа, тогда как Фабрика может создавать примитивы и функции JavaScript".
Ответ 2
Аллернхвким первоначально опубликовал ответ на этот вопрос со ссылкой на свой блог, однако модератор удалил его. Это единственный пост, который я нашел, который не только говорит вам, как сделать то же самое с сервисом, провайдером и фабрикой, но также рассказывает, что вы можете сделать с провайдером, чего не можете с фабрикой, и с завод, который вы не можете с обслуживанием.
Прямо из его блога:
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;
});
Посмотрите, как это буквально завод по производству автомобилей.
Вывод из его блога довольно хорош:
В заключение,
---------------------------------------------------
| Provider| Singleton| Instantiable | Configurable|
---------------------------------------------------
| Factory | Yes | Yes | No |
---------------------------------------------------
| Service | Yes | No | No |
---------------------------------------------------
| Provider| Yes | Yes | Yes |
---------------------------------------------------
-
Используйте Service, когда вам нужен простой объект, такой как Hash, например, {foo; 1, bar: 2}. Его легко кодировать, но вы не можете создать его экземпляр.
-
Используйте Factory, когда вам нужно создать экземпляр объекта, то есть new Customer(), new Comment() и т.д.
-
Используйте провайдера, когда вам нужно его настроить. т.е. тестовый URL, QA URL, производственный URL.
Если вы обнаружите, что вы просто возвращаете объект на фабрику, вам, вероятно, следует использовать сервис.
Не делай этого:
app.factory('CarFactory', function() {
return {
numCylinder: 4
};
});
Используйте сервис вместо:
app.service('CarService', function() {
this.numCylinder = 4;
});
Ответ 3
Концепция всех этих провайдеров намного проще, чем кажется на первый взгляд. Если вы рассекаете поставщика и вынимаете разные части, это становится очень ясным.
Проще говоря, каждый из этих провайдеров является специализированной версией другого, в следующем порядке: provider
> factory
> value
/constant
/service
.
До тех пор, пока провайдер делает все возможное, вы можете использовать провайдера дальше по цепочке, что приведет к написанию меньшего количества кода. Если он не выполняет то, что вы хотите, вы можете пойти вверх по цепочке, и вам просто нужно будет написать больше кода.
Это изображение иллюстрирует, что я имею в виду, на этом изображении вы увидите код для провайдера с выделенными частями, показывающими, какие части провайдера могут быть использованы для создания фабрики, стоимости и т.д.
(источник: simplygoodcode.com)
Для получения более подробной информации и примеров из поста в блоге, где я получил изображение, перейдите по ссылке: http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
Ответ 4
Оба factory и службы приводят к одноточечным объектам, которые могут быть настроены поставщиками и введены в контроллеры и блоки запуска. С точки зрения инъектора, нет никакой разницы, был ли объект получен из factory или службы.
Итак, когда использовать factory и когда использовать услугу? Это сводится к вашим предпочтениям в кодировании, и ничего больше. Если вам нравится модульный шаблон JS, перейдите к factory. Если вам нравится стиль конструктора ( "класс" ), перейдите к службе. Обратите внимание, что оба стиля поддерживают частные члены.
Преимущество службы может заключаться в том, что она более интуитивно понятна с точки зрения ООП: создайте "класс" и совместно с провайдером повторно используйте один и тот же код между модулями и измените поведение объектов-экземпляров просто путем предоставления различных параметров конструктору в блоке конфигурации.
Ответ 5
Нет ничего, что 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 не имеет этих недостатков. Я бы порекомендовал использовать его по умолчанию.
Ответ 6
Даже когда говорят, что все сервисы и заводы однотонные, я не согласен с этим на 100 процентов. Я бы сказал, что фабрики не одиночные, и это точка моего ответа. Я бы действительно подумал о имени, которое определяет каждый компонент (Service/ Factory), я имею в виду:
A factory, потому что он не является одиночным, вы можете создавать столько, сколько хотите, когда вы вводите, поэтому он работает как объект factory. Вы можете создать factory объекта вашего домена и работать более комфортно с этими объектами, которые могут быть похожими на объект вашей модели. Когда вы извлекаете несколько объектов, вы можете отображать их в этих объектах, и они могут действовать как другой слой между DDBB и моделью AngularJs. Вы можете добавлять методы к объектам, чтобы вы ориентировались на объекты немного больше вашего приложения AngularJs.
Между тем служба - это одиночный элемент, поэтому мы можем создать только один вид, возможно, не создадим, но у нас есть только один экземпляр, когда мы вводим в контроллер, поэтому служба больше похожа на общая служба (вызовы отдыха, функциональность..) для контроллеров.
Концептуально вы можете думать, что службы предоставляют услугу, фабрики могут создавать несколько экземпляров (объектов) класса
Ответ 7
Услуги
Синтаксис: module.service('serviceName', function);
Результат. При объявлении serviceName в качестве аргумента для инъекции вам будет предоставлен фактический справочник функций, переданный модулю service.service.
Использование. Может быть полезно для совместного использования служебных функций, которые полезны для вызова, просто добавляя() к ссылке с введенной функцией. Также можно запустить с помощью injectedArg.call(this) или аналогичного.
Заводы
Синтаксис: module.factory('factoryName', function);
Результат: при объявлении имени factoryName в качестве аргумента для инъекции вам будет предоставлено значение, возвращаемое вызовом ссылки на функцию, переданной модулю .factory.
Использование. Может оказаться полезным для возврата функции класса, которая затем может быть создана для создания экземпляров.
Провайдеры
Синтаксис: module.provider('providerName', function);
Результат. При объявлении имени поставщика в качестве аргумента для инъекции вам будет предоставлено значение, возвращаемое при вызове метода $get ссылки на функцию, переданной модулю .provider.
Использование. Может оказаться полезным для возврата функции класса, которая затем может быть создана для создания экземпляров, но перед введением требуется какая-то конфигурация. Возможно, полезно для классов, которые многократно используются для разных проектов? Еще один туманный на этом.
Ответ 8
Можно использовать способ: создать объект или 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();
})
Примечание:
-
Служба
- по умолчанию возвращает объект, а не функцию конструктора.
- Итак, почему для функции конструктора установлено значение this.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();
})
Примечание:
- factory по умолчанию возвращает конструктор, а не объект.
- Итак, почему новый объект может быть создан с помощью функции-конструктора.
Создать сервис для простого доступа к простым функциям
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()
})
Заключение:
- вы можете использовать способ, которым хотите, создавать ли новый объект или
просто для доступа к простым функциям
- Не будет никакого удара по производительности, используя один над другим
- Оба являются одноэлементными объектами, и для каждого приложения создается только один экземпляр.
- Быть только одним экземпляром, где передается их ссылка.
- В angular документация factory называется службой, а также служба называется службой.
Ответ 9
Фабрика и Сервис - наиболее часто используемый метод. Единственная разница между ними заключается в том, что метод Service работает лучше для объектов, которым требуется иерархия наследования, тогда как Factory может создавать примитивы и функции JavaScript.
Функция Provider является основным методом, а все остальные являются просто синтаксическим сахаром. Вам это нужно, только если вы создаете многократно используемый фрагмент кода, который требует глобальной настройки.
Существует пять способов создания сервисов: Value, Factory, Service, Provider и Constant. Вы можете узнать больше об этом здесь угловом сервисе, эта статья объясняет все эти методы на практических демонстрационных примерах.
,