it-swarm.com.ru

AngularJS: Когда использовать сервис вместо фабрики

Пожалуйста, потерпите меня здесь. Я знаю, что есть другие ответы, такие как: AngularJS: Сервис против провайдера против фабрики

Однако я до сих пор не могу понять, когда вы будете использовать сервис вместо фабрики.

Из того, что я могу сказать, фабрика обычно используется для создания "общих" функций, которые могут вызываться несколькими контроллерами: Создание общих функций контроллера

Документы Angular, похоже, предпочитают заводские, а не сервисные. Они даже ссылаются на "сервис", когда используют фабрику, что еще более запутанно! http://docs.angularjs.org/guide/dev_guide.services.creating_services

Так когда же можно будет использовать сервис?

Есть ли что-то, что только возможно или намного проще сделать с помощью сервиса?

Есть что-нибудь другое, что происходит за кулисами? Различия производительности/памяти?

Вот пример. Кроме метода объявления, они кажутся идентичными, и я не могу понять, почему я сделал бы одно против другого. http://jsfiddle.net/uEpkE/

Обновление: Из ответа Томаса, похоже, подразумевается, что сервис предназначен для более простой логики и фабрики для более сложной логики с закрытыми методами, поэтому я обновил код скрипты ниже, и кажется, что оба способны поддерживать частные функции?

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()
    ];
}
292
user1941747

Объяснение

Здесь есть разные вещи:

Первый:

  • Если вы используете сервис, вы получите экземпляр функции (ключевое слово "this").
  • Если вы используете фабрику, вы получите возвращаемое значение, вызвав ссылку на функцию (оператор return в фабрике).

ref: angular.service vs angular.factory

Второе:

Имейте в виду, что все провайдеры в AngularJS (стоимость, константа, услуги, фабрики) являются одиночками!

Третье:

Использование одного или другого (сервис или фабрика) о стиле кода. Но общий способ в AngularJS - это использование фабрики .

Зачем ?

Потому что "Фабричный метод является наиболее распространенным способом получения объектов в систему внедрения зависимостей AngularJS. Он очень гибкий и может содержат сложную логику создания. Поскольку фабрики являются обычными функциями, мы также можем воспользоваться новой лексической областью для моделирования "частных" переменных. Это очень полезно, поскольку мы можем скрыть детали реализации данного сервиса. "

( ref : http://www.Amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821 ).


Использование

Служба: Может быть полезна для совместного использования служебных функций, которые полезно вызывать, просто добавляя () в ссылку на введенную функцию. Также может быть запущен с injectedArg.call(this) или подобным.

Factory: Может быть полезно для возврата функции "class", которая затем может быть новой для создания экземпляров.

Итак, используйте фабрику, когда у вас есть сложная логика в вашем сервисе и вы не хотите раскрывать эту сложность .

В других случаях , если вы хотите вернуть экземпляр службы, просто используйте службу .

Но я думаю, что со временем вы увидите, что будете использовать фабрику в 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 . Если вы хотите, чтобы ваша функция создавалась с помощью нового оператора, используйте сервис. Если вы не знаете разницу, используйте фабрику. "


ОБНОВЛЕНИЕ:

Команда AngularJS выполняет свою работу и дает объяснения: http://docs.angularjs.org/guide/providers

И с этой страницы:

"Фабрика и Сервис - наиболее часто используемые рецепты. Единственное отличие между ними состоит в том, что Сервисный рецепт работает лучше для объектов пользовательского типа, тогда как Фабрика может создавать примитивы и функции JavaScript".

277
Thomas Pons

allernhwkim первоначально опубликовано ответ по этому вопросу ссылка на его блог , однако модератор удалил его. Это единственный пост, который я нашел, который не только говорит вам, как сделать то же самое с сервисом, провайдером и фабрикой, но также рассказывает, что вы можете сделать с провайдером, чего не можете с фабрикой, и с завод, который вы не можете с обслуживанием.

Прямо из его блога:

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         |       
---------------------------------------------------  
  1. Используйте Service, когда вам нужен простой объект, такой как Hash, например, {foo; 1, bar: 2} Код легко написать, но вы не можете создать его экземпляр.

  2. Используйте Factory, когда вам нужно создать экземпляр объекта, то есть new Customer (), new Comment () и т.д.

  3. Используйте провайдера, когда вам нужно его настроить. то есть тестовый URL, QA URL, производственный URL.

Если вы обнаружите, что вы просто возвращаете объект на фабрику, вам, вероятно, следует использовать сервис.

Не делай этого:

app.factory('CarFactory', function() {
    return {
        numCylinder: 4
    };
});

Используйте сервис вместо:

app.service('CarService', function() {
    this.numCylinder = 4;
});
109
Jonathan.

Концепция всех этих провайдеров намного проще, чем кажется на первый взгляд. Если вы рассекаете поставщика и вынимаете разные части, это становится очень ясным.

Проще говоря, каждый из этих поставщиков является специализированной версией другого в следующем порядке: provider> factory> value/constant/service.

До тех пор, пока провайдер делает все возможное, вы можете использовать провайдера дальше по цепочке, что приведет к написанию меньшего количества кода. Если он не выполняет то, что вы хотите, вы можете пойти вверх по цепочке, и вам просто нужно написать больше кода.

Это изображение иллюстрирует то, что я имею в виду, на этом изображении вы увидите код для провайдера с выделенными частями, показывающими, какие части провайдера могут быть использованы для создания фабрики, стоимости и т.д.

провайдеры, фабрики, сервисы и т.д. AngularJS - это одно и то же http://www.simplygoodcode.com/wp-content/uploads/2015/11/angularjs-provider-service-factory-highlight.png знак равно

Для получения более подробной информации и примеров из поста в блоге, где я получил изображение, перейдите по адресу: http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory- в-angularjs /

19
Luis Perez

И фабрика, и сервис приводят к созданию одноэлементных объектов, которые могут настраиваться поставщиками и вводиться в контроллеры и блоки выполнения. С точки зрения инженера, нет абсолютно никакой разницы, поступил ли объект с фабрики или из службы.

Итак, когда использовать фабрику, а когда использовать сервис? Это сводится к вашему предпочтению кодирования, и ничего больше. Если вам нравится модульный шаблон JS, то идите на завод. Если вам нравится стиль функции конструктора ("class"), тогда переходите на сервис. Обратите внимание, что оба стиля поддерживают закрытые члены.

Преимущество службы может заключаться в том, что она является более интуитивной с точки зрения OOP: создайте "класс" и, совместно с поставщиком, повторно используйте один и тот же код в разных модулях и измените поведение создаваемые объекты просто предоставляя различные параметры конструктору в блоке конфигурации.

8
Steve Lang

Даже когда они говорят, что все сервисы и фабрики одноразовые, я не согласен на 100% с этим. Я бы сказал, что фабрики - это не одиночки, и в этом смысл моего ответа. Я бы действительно подумал об имени, которое определяет каждый компонент (Service/Factory), я имею в виду:

A factory потому что это не синглтон, вы можете создать столько, сколько вы хотите, когда вы вводите, поэтому он работает как фабрика объектов. Вы можете создать фабрику сущности вашего домена и более комфортно работать с этими объектами, которые могут быть похожи на объект вашей модели. Когда вы извлекаете несколько объектов, вы можете отобразить их в этих объектах, и он может действовать как еще один слой между DDBB и моделью AngularJs. Вы можете добавлять методы к объектам, чтобы ориентировать их на объекты немного больше, чем в приложении AngularJs.

Между тем, service является одиночным, поэтому мы можем создать только 1 из них, может быть, не создавать, но у нас есть только 1 экземпляр, когда мы внедряем в контроллер, поэтому сервис больше похож на обычный сервис ( остальные вызовы, функционал ..) к контролерам.

Концептуально вы можете думать, как сервисы предоставляют сервис, фабрики могут создавать несколько экземпляров (объектов) класса

2
francisco J Jimenez Garcia

Фабрика не может ничего сделать или сделать лучше по сравнению с Сервисом. И наоборот. Фабрика просто кажется более популярной. Причиной этого является удобство работы с частными/публичными членами. Сервис будет более неуклюжим в этом отношении. При кодировании Сервиса вы стремитесь сделать ваши члены объекта публичными с помощью ключевого слова "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 использует ключевое слово "new" для создания службы для вас, поэтому экземпляр 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'  

Но с большой константой Service это может сделать код плохо читаемым. Более того, прототипы Сервиса не будут видеть приватных участников - им будут доступны только публичные:

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 нет этих недостатков. Я бы порекомендовал использовать его по умолчанию.

2
Andrew Krook

услуги

синтаксис: module.service ('имя_службы', функция); Результат: При объявлении serviceName в качестве вводимого аргумента вам будет предоставлена ​​фактическая ссылка на функцию, переданную в module.service.

Использование: Может быть полезно для совместного использования служебных функций, которые полезно вызывать, просто добавляя () к ссылке на введенную функцию. Также может быть запущен с помощью injectedArg.call (this) или аналогичным.

заводы

синтаксис: module.factory ('factoryName', функция);

Результат: При объявлении factoryName в качестве вводимого аргумента вам будет предоставлено значение, возвращаемое путем вызова ссылки на функцию, переданной в module.factory.

Использование: Может быть полезно для возврата функции 'class', которая затем может быть новой для создания экземпляров.

Провайдеры

синтаксис: module.provider ('providerName', функция);

Результат: При объявлении providerName в качестве вводимого аргумента вам будет предоставлено значение, возвращаемое путем вызова метода $ get ссылки на функцию, переданной в module.provider.

Использование: Может быть полезно для возврата функции 'class', которая затем может быть new'ed для создания экземпляров, но которая требует некоторой конфигурации перед вводом. Возможно, полезно для классов, которые можно использовать в разных проектах? Все еще немного смутно на этом.

0
Nishant Upadhyay

Фабрика и Сервис - наиболее часто используемый метод. Единственная разница между ними заключается в том, что метод Service работает лучше для объектов, которым требуется иерархия наследования, тогда как Factory может создавать примитивы и функции JavaScript.

Функция Provider является основным методом, а все остальные являются просто синтаксическим сахаром. Вам это нужно, только если вы создаете многократно используемый фрагмент кода, который требует глобальной настройки.

Существует пять способов создания сервисов: Value, Factory, Service, Provider и Constant. Вы можете узнать больше об этом здесь angular service , эта статья объясняет все эти методы на практических демонстрационных примерах.

,.

0
user3114005

Можно использовать оба так, как вы хотите: будь создать объект или j только для доступа к функциям из обоих


Вы можете создать новый объект из сервиса

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.
  • Благодаря этому сервис вернет объект, но только внутри этого объекта будет функция конструктора, которая будет использоваться для создания нового объекта;

Вы можете создать новый объект с фабрики

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()
})

Создать фабрику для простого доступа к простым функциям

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 документации фабрика называется сервисом, а также сервис называется сервисом.
0
vijay