Насколько я понимаю, когда я на фабрике, я возвращаю объект, который вводится в контроллер. Находясь внутри службы, я имею дело с объектом, использующим this
и не возвращающим ничего.
Я исходил из того, что служба всегда была одноэлементной , и что новый фабричный объект вводится в каждый контроллер. Однако, как выясняется, заводской объект тоже является синглтоном?
Пример кода для демонстрации:
var factories = angular.module('app.factories', []);
var app = angular.module('app', ['ngResource', 'app.factories']);
factories.factory('User', function () {
return {
first: 'John',
last: 'Doe'
};
});
app.controller('ACtrl', function($scope, User) {
$scope.user = User;
});
app.controller('BCtrl', function($scope, User) {
$scope.user = User;
});
При изменении user.first
в ACtrl
ней получается, что user.first
в BCtrl
также изменяется, например , User
одноэлементно?
Мое предположение было, что новый экземпляр был введен в контроллер с фабрикой?
Ответы:
Все угловые услуги являются одиночными :
Документы (см. Раздел «Службы в виде синглтонов» ): https://docs.angularjs.org/guide/services.
В основном разница между сервисом и фабрикой заключается в следующем:
Проверьте эту презентацию о $ обеспечить: http://slides.wesalvaro.com/20121113/#/
Эти слайды были использованы на одном из собраний AngularJ: http://blog.angularjs.org/2012/11/more-angularjs-meetup-videos.html
источник
new
этого.Для меня откровение пришло, когда я понял, что все они работают одинаково: запустив что-то один раз , сохранив полученное значение, а затем выкашливая то же самое сохраненное значение, когда на него ссылается через инъекцию зависимостей.
Скажем, у нас есть:
Разница между тремя заключается в том, что:
a
сохраненное значение приходит от запускаfn
, другими словами:fn()
b
сохраненное значение приходит изnew
ingfn
, другими словами:new fn()
c
хранимое значение приходит с первого получения экземпляра с помощьюnew
ingfn
, а затем запускает$get
метод экземпляраэто означает, что внутри angular есть что-то вроде объекта кэша, значение которого для каждой инъекции присваивается только один раз, когда они были введены впервые, и где:
Вот почему мы используем
this
в сервисах, а определяемthis.$get
в провайдерах.Надеюсь это поможет.
источник
живой пример
пример "Привет, мир"
с
factory
/service
/provider
:источник
Существует также способ вернуть функцию конструктора, чтобы вы могли возвращать новые классы на фабриках, например:
Так что вы можете сделать это в контроллере, который использует MyObjectWithParam:
Смотрите здесь полный пример:
http://plnkr.co/edit/GKnhIN?p=preview
А вот страницы группы Google, где это обсуждалось:
https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/b8hdPskxZXsJ
источник
App.factory('MyObjectWithParam', ['$injector', function ($injector) { return function(name) { return $injector.instantiate(MyObjectWithParam,{ name: name }); }; }]);
Узнайте больше об этом здесь: docs.angularjs.org/tutorial/step_05.service
вместо этого?.factory
по сравнению с.service
?new Car('BMW')
иnew Car('Ford')
они не разделяют одни и те же переменные и все.Вот основные отличия:
Сервисы
Синтаксис:
module.service( 'serviceName', function );
Результат: при объявлении serviceName в качестве вводимого аргумента вам будет предоставлен экземпляр функции, переданной в
module.service
.Использование: Может быть полезно для совместного использования служебных функций , которые полезно вызывать, просто добавляя () к введенной ссылке на функцию. Может также работать с
injectedArg.call( this )
или аналогичным.Заводы
Синтаксис:
module.factory( 'factoryName', function );
Результат: при объявлении factoryName в качестве вводимого аргумента вам будет предоставлено значение, возвращаемое путем вызова ссылки на функцию, переданной в
module.factory
.Использование: Может быть полезно для возврата функции 'class', которая затем может быть new'ed для создания экземпляров.
Также ознакомьтесь с документацией по AngularJS и схожим вопросам о стековом потоке, запутанном в отношении сервиса и фабрики .
Вот пример использования сервисов и фабрики . Узнайте больше о сервисе AngularJS vs factory .
источник
В дополнение к первому ответу, я думаю, .service () предназначен для людей, которые написали свой код в более объектно-ориентированном стиле (C # / Java) (используя это ключевое слово и создавая объект с помощью функции prototype / Constructor).
Фабрика предназначена для разработчиков, которые пишут код, более естественный для javascript / функционального стиля кодирования.
Взгляните на исходный код метода .service и .factory внутри angular.js - внутренне все они вызывают метод провайдера:
источник
Очень просто:
.service - зарегистрированная функция будет вызываться как конструктор (также известный как newed)
.factory - зарегистрированная функция будет вызываться как простая функция
Оба они вызываются один раз, в результате чего получается одноэлементный объект, который внедряется в другие компоненты вашего приложения.
источник
Все провайдеры работают одинаково. Различные методы
service
,factory
,provider
просто позволяют сделать то же самое в меньше кода.PS Там же
value
иconstant
.Каждый особый случай по цепочке, начиная с
provider
и заканчиваяvalue
имеет дополнительное ограничение. Таким образом, чтобы решить между ними, вы должны спросить себя, что позволит вам выполнить то, что вы хотите, с меньшим количеством кода.Вот картинка, которая показывает вам, что я имею в виду:
Вы можете разбить справочное руководство на пост в блоге, с которого я получил это изображение:
http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
источник
console.log()
и вводя в несколько контроллеров.Вот еще несколько примеров услуг по сравнению с фабриками, которые могут быть полезны, чтобы увидеть разницу между ними. По сути, к сервису обращаются «new ...», он уже создан. Фабрика не создается автоматически.
Основные примеры
Вернуть объект класса, который имеет единственный метод
Вот сервис, который имеет единственный метод:
Вот фабрика, которая возвращает объект с методом:
Вернуть значение
Фабрика, которая возвращает список чисел:
Сервис, который возвращает список номеров:
Вывод в обоих случаях одинаков, список номеров.
Расширенные примеры
Переменные класса с использованием фабрик
В этом примере мы определяем CounterFactory, он увеличивает или уменьшает счетчик, и вы можете получить текущий счетчик или узнать, сколько объектов CounterFactory было создано:
Мы используем
CounterFactory
для создания нескольких счетчиков. Мы можем получить доступ к переменной класса, чтобы увидеть, сколько счетчиков было создано:Выход этого кода:
источник
«Фабрика» и «Сервис» - это разные способы выполнения DI (инжекция зависимости) в угловых.
Поэтому, когда мы определяем DI, используя «сервис», как показано в коде ниже. Это создает новый экземпляр GLOBAL объекта «Logger» и внедряет его в функцию.
Когда вы определяете DI, используя «фабрику», он не создает экземпляр. Он просто передает метод, и позже потребитель внутри должен сделать вызовы фабрике для экземпляров объекта.
Ниже приведено простое изображение, которое наглядно показывает, как процесс DI для «Service» отличается от «Factory».
Фабрика должна использоваться, когда мы хотим создавать различные типы объектов в зависимости от сценариев. Например, в зависимости от сценария мы хотим создать простой объект «Клиент» или «Клиент» с объектом «Адрес» или «Клиент» с объектом «Телефон». Вот подробное объяснение этого пункта
Служба должна использоваться, когда у нас есть служебные или общие функции, которые нужно внедрить, такие как Utility, Logger, Error handler и т. Д.
источник
Сервисный стиль: ( возможно, самый простой ) возвращает фактическую функцию: полезно для совместного использования служебных функций, которые полезно вызывать, просто добавляя () к ссылке на вставленную функцию.
Сервис в AngularJS - это одноэлементный объект JavaScript, который содержит набор функций
Фабричный стиль: ( более сложный, но более сложный ) возвращает возвращаемое значение функции: создать экземпляр объекта типа new Object () в java.
Фабрика - это функция, которая создает значения. Когда службе, контроллеру и т. Д. Требуется значение, введенное фабрикой, фабрика создает значение по требованию. После создания значение используется повторно для всех служб, контроллеров и т. Д., Которым оно необходимо ввести.
Стиль провайдера : ( полнофункциональная, конфигурируемая версия ) возвращает выходные данные функции $ get функции: Configurable.
Поставщики в AngularJS - это самая гибкая форма фабрики, которую вы можете создать. Вы регистрируете провайдера в модуле так же, как в сервисе или на фабрике, за исключением того, что вы используете вместо него функцию provider ().
src jenkov
jsbin
jsfiddle
источник
Основное отличие состоит в том, что провайдер позволяет устанавливать значения функций-примитивов (не-объектов), массивов или функций обратного вызова в объявленную фабрикой переменную, и, таким образом, при возврате объекта он должен быть явно объявлен и возвращен.
С другой стороны, сервис может использоваться только для установки объявленной переменной сервиса для объекта, поэтому мы можем избежать явного создания и возврата объектов, в то время как с другой стороны это позволяет использовать ключевое слово this .
Или, кратко говоря, « поставщик - это более общая форма, в то время как сервис ограничен только объектами».
источник
Вот как я понял разницу между ними с точки зрения шаблонов проектирования:
Сервис : вернуть тип, который будет обновлен для создания объекта этого типа. Если используется аналогия с Java, Service возвращает определение класса Java .
Фабрика : возвращает конкретный объект, который можно сразу использовать. В аналогии с Java фабрика возвращает объект Java .
Часть, которая часто смущает людей (в том числе и меня), заключается в том, что когда вы внедряете Сервис или Фабрику в свой код, они могут использоваться одинаково, то, что вы получаете в своем коде в обоих случаях, является конкретным объектом, который вы можете немедленно вызвать. Что означает в случае Сервиса, угловые звонки «новые» в декларации сервиса от вашего имени. Я думаю, что это замысловатая концепция.
источник
Это был бы лучший и краткий ответ для понимания Service Vs Factory Vs Provider
Источник : https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/HuZsOsMvKv4J
Вот что Бен говорит с демонстрацией http://jsbin.com/ohamub/1/edit?html,output
«В коде есть комментарии, иллюстрирующие основные отличия, но я их немного расширю здесь. В качестве примечания, я просто обдумываю это, поэтому, если я скажу что-нибудь неправильное, пожалуйста, дайте мне знать.
Сервисы
Синтаксис : module.service ('serviceName', функция);
Результат : при объявлении serviceName в качестве вводимого аргумента вам будет предоставлена фактическая ссылка на функцию, переданная в module.service.
Использование : Может быть полезно для совместного использования служебных функций, которые полезно вызывать, просто добавляя () к введенной ссылке на функцию. Также может быть запущен с injectedArg.call (this) или аналогичным.
Заводы
Синтаксис : module.factory ('factoryName', функция);
Результат : при объявлении factoryName в качестве вводимого аргумента вам будет предоставлено значение, возвращаемое путем вызова ссылки на функцию, переданной в module.factory.
Использование : Может быть полезно для возврата функции 'class', которая затем может быть new'ed для создания экземпляров.
Провайдеры
Синтаксис : module.provider ('providerName', функция);
Результат : при объявлении providerName в качестве вводимого аргумента вам будет предоставлено значение, возвращаемое путем вызова метода $ get ссылки на функцию, переданной в module.provider.
Использование : Может быть полезно для возврата функции 'class', которая затем может быть добавлена new для создания экземпляров, но которая требует некоторой конфигурации перед внедрением. Возможно, полезно для классов, которые можно использовать в разных проектах? Все еще немного смутно на этом. "Бен
источник
У меня было некоторое замешательство, и я изо всех сил стараюсь дать простое объяснение здесь. Надеюсь, это поможет!
angular .factory
иangular .service
оба используются для инициализации службы и работают одинаково.Разница лишь в том, как вы хотите инициализировать свой сервис.
Оба синглтоны
завод
app.factory (
<service name>
,<function with a return value>
)Если вы хотите инициализировать свой сервис из имеющейся у вас функции с возвращаемым значением , вы должны использовать этот
factory
метод.например
При введении этой услуги (например, вашему контроллеру):
myService()
) , чтобы вернуть объектобслуживание
app.service (
<service name>
,<constructor function>
)Если вы хотите инициализировать свой сервис из функции конструктора (используя
this
ключевое слово), вы должны использовать этотservice
метод.например
При введении этой услуги (например, вашему контроллеру):
new
заданную функцию (какnew myService()
) для возврата объектаПРИМЕЧАНИЕ: если вы используете
factory
с<constructor function>
илиservice
с<function with a return value>
, это не будет работать.Примеры - ДЕМО
источник
Это то, что помогло мне понять разницу, благодаря сообщению в блоге Паскаля Прехта.
Служба - это метод в модуле, который принимает имя, и функция, которая определяет службу. Вы можете внедрить и использовать этот конкретный сервис в других компонентах, таких как контроллеры, директивы и фильтры. Фабрика - это метод в модуле, который также принимает имя и функцию, которые определяют фабрику. Мы также можем внедрить и использовать его так же, как мы это сделали с сервисом.
Объекты, созданные с помощью new, используют значение свойства prototype их функции конструктора в качестве своего прототипа, поэтому я обнаружил код Angular, который вызывает Object.create (), который, как я считаю, является функцией конструктора службы, когда она создается. Однако фабричная функция - это на самом деле просто вызываемая функция, поэтому мы должны возвращать литерал объекта для фабрики.
Вот угловой код 1.5, который я нашел для фабрики:
Фрагмент углового исходного кода для функции factory ():
Он принимает имя и фабричную функцию, которые передаются, и возвращает провайдера с тем же именем, у которого есть метод $ get, который является нашей фабричной функцией. Всякий раз, когда вы запрашиваете у инжектора конкретную зависимость, он в основном запрашивает у соответствующего провайдера экземпляр этой службы, вызывая метод $ get (). Вот почему $ get () требуется при создании провайдеров.
Вот угловой код 1.5 для обслуживания.
Оказывается, когда мы вызываем service (), он на самом деле вызывает factory ()! Тем не менее, он не просто передает нашу функцию конструктора сервиса на завод. Он также передает функцию, которая просит инжектор создать объект с помощью данного конструктора.
Другими словами, если мы внедряем MyService где-то, что происходит в коде:
Чтобы повторить это снова, сервис вызывает фабрику, которая является методом $ get () соответствующего провайдера. Более того, $ injector.instantiate () - это метод, который в конечном итоге вызывает Object.create () с функцией конструктора. Вот почему мы используем «это» в сервисах.
Для ES5 не имеет значения, какой мы используем: service () или factory (), всегда вызывается фабрика, которая создает провайдера для нашего сервиса.
Вы можете сделать то же самое с услугами, хотя. Однако служба - это функция конструктора, которая не мешает нам возвращать объектные литералы. Таким образом, мы можем взять наш сервисный код и записать его так, чтобы он в основном делал то же самое, что и наша фабрика, или, другими словами, вы можете написать сервис как фабрику для возврата объекта.
Почему большинство людей рекомендуют использовать фабрики вместо услуг? Это лучший ответ, который я когда-либо видел, из книги Павла Козловского: освоение разработки веб-приложений с помощью AngularJS.
источник
this
ключевое слово для определения функции.$get
вы определяете , и он может быть использован , чтобы получить объект , который возвращает данные.источник
В AngularJS есть три способа работы с бизнес-логикой: ( Вдохновленный курсом Яакова Coursera AngularJS ):
Здесь мы будем только говорить о Service vs Factory
СЕРВИС :
Синтаксис:
app.js
index.html
Основные особенности Сервиса:
Lazily Instantiated : если сервис не внедрен, он никогда не будет создан. Таким образом, чтобы использовать его, вам придется ввести его в модуль.
Singleton : если он внедрен в несколько модулей, все будут иметь доступ только к одному конкретному экземпляру. Поэтому очень удобно обмениваться данными между разными контроллерами.
ФАБРИКА
Теперь поговорим о фабрике в AngularJS
Сначала давайте посмотрим на синтаксис :
app.js :
Теперь с помощью двух выше в контроллере:
Особенности Фабрики:
Эти виды услуг следуют шаблону дизайна фабрики . Фабрика может рассматриваться как центральное место, которое создает новые объекты или методы.
Это не только производит одиночные, но и настраиваемые сервисы.
.service()
Метод является завод , который всегда производит один и тот же тип сервиса, который одноэлементно. Нет простого способа настроить его поведение. Этот.service()
метод обычно используется в качестве ярлыка для чего-то, что не требует какой-либо настройки.источник
Для краткого и простого объяснения см. Https://stackoverflow.com/a/26924234/5811973 .
Для подробного объяснения см. Https://stackoverflow.com/a/15666049/5811973 .
Также из документации angularJs:
источник
Вы можете понять разницу с этой аналогией - рассмотрите разницу между нормальной функцией, которая будет возвращать некоторое значение, и функцией конструктора, которая будет создана с использованием нового ключевого слова. Таким образом, создание фабрики аналогично созданию нормальной функции, которая будет возвращать некоторое значение (примитив или объект), тогда как создание службы похоже на создание функции конструктора (класс OO), для которой мы можем создать экземпляр, используя ключевое слово new. Единственное, что следует отметить, это то, что когда мы используем метод Service для создания сервисов, он автоматически создает его экземпляр, используя механизм внедрения зависимостей, поддерживаемый AngularJS.
источник