Según tengo entendido, cuando dentro de una fábrica devuelvo un objeto que se inyecta en un controlador. Cuando estoy dentro de un servicio, estoy tratando con el objeto usando this
y sin devolver nada.
Supuse que un servicio siempre era un singleton y que se inyectaba un nuevo objeto de fábrica en cada controlador. Sin embargo, como resultado, ¿un objeto de fábrica también es un singleton?
Código de ejemplo para demostrar:
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;
});
Al cambiar user.first
en ACtrl
resulta que user.first
en BCtrl
también se cambia, por ejemplo, User
es un producto único?
¿Supuse que se inyectó una nueva instancia en un controlador con una fábrica?
Respuestas:
Todos los servicios angulares son singletons :
Documentos (ver Servicios como singletons ): https://docs.angularjs.org/guide/services
Básicamente, la diferencia entre el servicio y la fábrica es la siguiente:
Vea esta presentación sobre $ provide: http://slides.wesalvaro.com/20121113/#/
Esas diapositivas se usaron en una de las reuniones de AngularJs: http://blog.angularjs.org/2012/11/more-angularjs-meetup-videos.html
fuente
new
.Para mí, la revelación llegó cuando me di cuenta de que todos funcionan de la misma manera: ejecutando algo una vez , almacenando el valor que obtienen, y luego tose ese mismo valor almacenado cuando se hace referencia a través de la inyección de dependencia.
Digamos que tenemos:
La diferencia entre los tres es que:
a
El valor almacenado proviene de la ejecuciónfn
, en otras palabras:fn()
b
El valor almacenado proviene denew
ingfn
, en otras palabras:new fn()
c
El valor almacenado proviene de obtener primero una instancianew
ingfn
y luego ejecutar un$get
método de la instancialo que significa que hay algo así como un objeto de caché dentro de angular, cuyo valor de cada inyección solo se asigna una vez, cuando se inyectaron la primera vez y donde:
Es por eso que usamos
this
en servicios y definimos athis.$get
en proveedores.Espero que esto ayude.
fuente
ejemplo en vivo
ejemplo de "hola mundo"
con
factory
/service
/provider
:fuente
También hay una manera de devolver una función de constructor para que pueda devolver clases nuevas en fábricas, como esta:
Entonces puede hacer esto en un controlador, que usa MyObjectWithParam:
Vea aquí el ejemplo completo:
http://plnkr.co/edit/GKnhIN?p=preview
Y aquí las páginas del grupo de Google, donde se discutió:
https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/b8hdPskxZXsJ
fuente
App.factory('MyObjectWithParam', ['$injector', function ($injector) { return function(name) { return $injector.instantiate(MyObjectWithParam,{ name: name }); }; }]);
Lea más sobre esto aquí: docs.angularjs.org/tutorial/step_05.service
en su lugar?.factory
en lugar de.service
?new Car('BMW')
ynew Car('Ford')
no comparten las mismas variables y todo.Aquí están las principales diferencias:
Servicios
Sintaxis:
module.service( 'serviceName', function );
Resultado: al declarar serviceName como un argumento inyectable, se le proporcionará la instancia de una función pasada a
module.service
.Uso: podría ser útil para compartir funciones de utilidad que son útiles para invocar simplemente agregando () a la referencia de función inyectada. También se puede ejecutar con
injectedArg.call( this )
o similar.Suerte
Sintaxis:
module.factory( 'factoryName', function );
Resultado: al declarar factoryName como argumento inyectable, se le proporcionará el valor que se devuelve invocando la referencia de función que se le pasó
module.factory
.Uso: podría ser útil para devolver una función de 'clase' que luego se puede actualizar para crear instancias.
También verifique la documentación de AngularJS y una pregunta similar sobre stackoverflow confundido sobre el servicio frente a la fábrica .
Aquí hay un ejemplo de uso de servicios y fábrica . Lea más sobre el servicio AngularJS vs fábrica .
fuente
Agregando a la primera respuesta, creo que .service () es para las personas que han escrito su código en un estilo más orientado a objetos (C # / Java) (usando esta palabra clave y instanciando objeto a través de la función prototipo / Constructor).
Factory es para desarrolladores que escriben código que es más natural para JavaScript / estilo funcional de codificación.
Eche un vistazo al código fuente de .service y .factory method dentro de angular.js - internamente todos llaman método de proveedor:
fuente
Muy simple:
.service: la función registrada se invocará como un constructor (también conocido como 'nuevo')
.factory: la función registrada se invocará como una función simple
Ambos se invocan una vez, lo que da como resultado un objeto singleton que se inyecta en otros componentes de su aplicación.
fuente
Todos los proveedores trabajan de la misma manera. Los diferentes métodos
service
,factory
,provider
solo permiten obtener el mismo resultado en menos código.PD También hay
value
yconstant
.Cada caso especial en la cadena que comienza
provider
y termina convalue
tiene una limitación adicional. Entonces, para decidir entre ellos, debe preguntarse qué le permite lograr lo que desea con menos código.Aquí hay una imagen que muestra lo que quiero decir:
Puede obtener un desglose y una guía de referencia en la publicación del blog. Obtuve esta imagen de:
http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
fuente
console.log()
e inyectando en múltiples controladores.Aquí hay algunos ejemplos más de servicios vs fábricas que pueden ser útiles para ver la diferencia entre ellos. Básicamente, un servicio tiene "nuevo ..." llamado, ya está instanciado. Una fábrica no se instancia automáticamente.
Ejemplos básicos
Devuelve un objeto de clase que tiene un método único
Aquí hay un servicio que tiene un único método:
Aquí hay una fábrica que devuelve un objeto con un método:
Devuelve un valor
Una fábrica que devuelve una lista de números:
Un servicio que devuelve una lista de números:
La salida en ambos casos es la misma, la lista de números.
Ejemplos avanzados
Variables de "clase" utilizando fábricas
En este ejemplo definimos un CounterFactory, incrementa o disminuye un contador y puede obtener el conteo actual u obtener cuántos objetos CounterFactory se han creado:
Usamos el
CounterFactory
para crear múltiples contadores. Podemos acceder a la variable de clase para ver cuántos contadores se crearon:La salida de este código es:
fuente
"Fábrica" y "Servicio" son diferentes formas de hacer DI (inyección de dependencia) en angular.
Entonces, cuando definimos DI usando "servicio" como se muestra en el código a continuación. Esto crea una nueva instancia GLOBAL del objeto "Logger" y la inyecta en la función.
Cuando define DI utilizando una "fábrica", no crea una instancia. Simplemente pasa el método y luego el consumidor internamente tiene que hacer llamadas a la fábrica para instancias de objetos.
A continuación se muestra una imagen simple que muestra visualmente cómo el proceso de DI para "Servicio" es diferente de "Fábrica".
Se debe usar Factory Cuando queremos crear diferentes tipos de objetos dependiendo de los escenarios. Por ejemplo, dependiendo del escenario, queremos crear un simple objeto "Cliente", o "Cliente" con objeto "Dirección" o "Cliente" con objeto "Teléfono". Aquí hay una explicación detallada de este párrafo.
El servicio debe usarse cuando tenemos utilidades o funciones compartidas para inyectar como utilidad, registrador, controlador de errores, etc.
fuente
Estilo de servicio : ( probablemente el más simple ) devuelve la función real: útil para compartir funciones de utilidad que son útiles para invocar simplemente agregando () a la referencia de función inyectada.
Un servicio en AngularJS es un objeto JavaScript singleton que contiene un conjunto de funciones
Estilo de fábrica : ( más complicado pero más sofisticado ) devuelve el valor de retorno de la función: instanciar un objeto como nuevo Object () en java.
La fábrica es una función que crea valores. Cuando un servicio, controlador, etc. necesita un valor inyectado de una fábrica, la fábrica crea el valor a pedido. Una vez creado, el valor se reutiliza para todos los servicios, controladores, etc. que lo necesitan inyectado.
Estilo del proveedor : ( versión completa, configurable ) devuelve el resultado de la función $ get de la función: Configurable.
Los proveedores en AngularJS son la forma más flexible de fábrica que puede crear. Usted registra un proveedor con un módulo tal como lo hace con un servicio o fábrica, excepto que utiliza la función de proveedor () en su lugar.
src jenkov
jsbin
jsfiddle
fuente
La diferencia básica es que el proveedor permite establecer valores primitivos (no objetos), de matriz o de función de devolución de llamada en la variable declarada de fábrica y, por lo tanto, si devuelve un objeto, debe declararse y devolverse explícitamente.
Por otro lado, un servicio solo se puede usar para establecer la variable declarada de servicio en un objeto, por lo que podemos evitar la creación explícita y la devolución de los objetos, mientras que, por otro lado, permite el uso de esta palabra clave.
O, en pocas palabras, "el proveedor es una forma más genérica, mientras que el servicio se limita a objetos solamente".
fuente
Así es como entendí la diferencia entre ellos en términos de patrones de diseño:
Servicio : Devuelve un tipo, que se renovará para crear un objeto de ese tipo. Si se utiliza la analogía Java, el Servicio devuelve una definición de Clase Java .
Fábrica : Devuelve un objeto concreto que puede usarse inmediatamente. En Java Analogy, Factory devuelve un objeto Java .
La parte que a menudo confunde a las personas (incluido yo mismo) es que cuando se inyecta un Servicio o una Fábrica en su código, se pueden usar de la misma manera, lo que se obtiene en su código en ambos casos es un objeto concreto que puede invocar de inmediato. Lo que significa que en el caso del Servicio, angular llama "nuevo" en la declaración del servicio en su nombre. Creo que este es un concepto complicado.
fuente
Esta sería la mejor y breve respuesta para comprender el servicio Vs Factory Vs Provider
Fuente : https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/HuZsOsMvKv4J
Aquí lo que dice Ben con una demostración http://jsbin.com/ohamub/1/edit?html,output
"Hay comentarios en el código que ilustran las principales diferencias, pero las expondré un poco aquí. Como nota, solo estoy entendiendo esto, así que si digo algo que está mal, avíseme.
Servicios
Sintaxis : module.service ('serviceName', function);
Resultado : al declarar serviceName como argumento inyectable, se le proporcionará la referencia de función real que se pasó a module.service.
Uso : podría ser útil para compartir funciones de utilidad que son útiles para invocar simplemente agregando () a la referencia de función inyectada. También se puede ejecutar con injectedArg.call (this) o similar.
Suerte
Sintaxis : module.factory ('factoryName', función);
Resultado : al declarar factoryName como argumento inyectable, se le proporcionará el valor que se devuelve invocando la referencia de función pasada a module.factory.
Uso : podría ser útil para devolver una función de 'clase' que luego se puede actualizar para crear instancias.
Proveedores
Sintaxis : module.provider ('providerName', function);
Resultado : al declarar providerName como argumento inyectable, se le proporcionará el valor que se devuelve invocando el método $ get de la referencia de función pasada a module.provider.
Uso : podría ser útil para devolver una función de 'clase' que luego se puede actualizar para crear instancias, pero que requiere algún tipo de configuración antes de ser inyectada. ¿Quizás útil para clases que son reutilizables en proyectos? Todavía un poco confuso en este caso "Ben
fuente
Tuve esta confusión por un tiempo y estoy haciendo mi mejor esfuerzo para proporcionar una explicación simple aquí. Espero que esto ayude!
angular .factory
yangular .service
ambos se usan para inicializar un servicio y trabajar de la misma manera.La única diferencia es cómo desea inicializar su servicio.
Ambos son Singletons
Fábrica
app.factory (
<service name>
,<function with a return value>
)Si desea inicializar su servicio desde una función que tiene con un valor de retorno , debe utilizar este
factory
método.p.ej
Al inyectar este servicio (por ejemplo, a su controlador):
myService()
) para devolver el objetoServicio
app.service (
<service name>
,<constructor function>
)Si desea inicializar su servicio desde una función de constructor (usando una
this
palabra clave), debe usar esteservice
método.p.ej
Al inyectar este servicio (por ejemplo, a su controlador):
new
utilizará su función (asnew myService()
) para devolver el objetoNOTA: Si usa
factory
con<constructor function>
oservice
con<function with a return value>
, no funcionará.Ejemplos: demostraciones
fuente
Esto es lo que me ayudó a entender la diferencia, gracias a una publicación de blog de Pascal Precht.
Un servicio es un método en un módulo que toma un nombre y una función que define el servicio. Puede inyectar y usar ese servicio en particular en otros componentes, como controladores, directivas y filtros. Una fábrica es un método en un módulo y también toma un nombre y una función que define la fábrica. También podemos inyectar y usarlo de la misma manera que lo hicimos con el servicio.
Los objetos creados con nuevo usan el valor de la propiedad prototipo de su función de constructor como su prototipo, por lo que encontré el código angular que llama a Object.create (), que creo que es la función de constructor de servicios cuando se instancia. Sin embargo, una función de fábrica es realmente solo una función que se llama, por lo que tenemos que devolver un objeto literal para la fábrica.
Aquí está el código angular 1.5 que encontré para la fábrica:
Fragmento de código fuente angular para la función factory ():
Toma el nombre y la función de fábrica que se pasa y devuelve un proveedor con el mismo nombre, que tiene un método $ get que es nuestra función de fábrica. Cada vez que le pide al inyector una dependencia específica, básicamente le pide al proveedor correspondiente una instancia de ese servicio, llamando al método $ get (). Es por eso que se requiere $ get () al crear proveedores.
Aquí está el código angular 1.5 para servicio.
¡Resulta que cuando llamamos al servicio (), en realidad llama a la fábrica ()! Sin embargo, no solo pasa nuestra función de constructor de servicios a la fábrica tal como está. También pasa una función que le pide al inyector que cree una instancia de un objeto por el constructor dado.
En otras palabras, si inyectamos MyService en algún lugar, lo que sucede en el código es:
Para volver a expresarlo, un servicio llama a una fábrica, que es un método $ get () en el proveedor correspondiente. Además, $ injector.instantiate () es el método que finalmente llama a Object.create () con la función de constructor. Es por eso que usamos "esto" en los servicios.
Para ES5, no importa cuál usemos: service () o factory (), siempre se llama una fábrica que crea un proveedor para nuestro servicio.
Sin embargo, también puede hacer exactamente lo mismo con los servicios. Sin embargo, un servicio es una función constructora que no nos impide devolver literales de objeto. Por lo tanto, podemos tomar nuestro código de servicio y escribirlo de una manera que básicamente haga exactamente lo mismo que nuestra fábrica o, en otras palabras, puede escribir un servicio como fábrica para devolver un objeto.
¿Por qué la mayoría de la gente recomienda usar fábricas en lugar de servicios? Esta es la mejor respuesta que he visto que proviene del libro de Pawel Kozlowski: Dominar el desarrollo de aplicaciones web con AngularJS.
fuente
this
palabra clave para definir la función.$get
usted define y puede usarse para obtener el objeto que devuelve los datos.fuente
Hay tres formas de manejar la lógica de negocios en AngularJS: ( Inspirado en el curso Coursera AngularJS de Yaakov ) que son:
Aquí solo vamos a hablar de Servicio vs Fábrica
Servicio :
Sintaxis:
app.js
index.html
Las principales características del servicio:
Instancia perezosa : si el servicio no se inyecta, no se instanciará nunca. Entonces, para usarlo, deberá inyectarlo en un módulo.
Singleton : si se inyecta en varios módulos, todos tendrán acceso a una sola instancia en particular. Por eso, es muy conveniente compartir datos entre diferentes controladores.
FÁBRICA
Ahora hablemos de la Fábrica en AngularJS
Primero echemos un vistazo a la sintaxis :
app.js :
Ahora usando los dos anteriores en el controlador:
Características de la fábrica:
Este tipo de servicios sigue el patrón de diseño de fábrica . La fábrica puede considerarse como un lugar central que crea nuevos objetos o métodos.
Esto no solo produce singleton, sino también servicios personalizables.
El
.service()
método es una fábrica que siempre produce el mismo tipo de servicio, que es un singleton. No hay una manera fácil de configurar su comportamiento. Ese.service()
método generalmente se usa como un acceso directo para algo que no requiere ninguna configuración en absoluto.fuente
Para una explicación breve y simple, consulte https://stackoverflow.com/a/26924234/5811973 .
Para obtener una explicación detallada, consulte https://stackoverflow.com/a/15666049/5811973 .
También de la documentación de angularJs:
fuente
Puede comprender la diferencia con esta analogía: considere la diferencia entre una función normal que devolverá algún valor y la función de constructor que se instanciará usando una nueva palabra clave, por lo que crear factory es similar a crear una función normal que devolverá algún valor (primitivo o un objeto), mientras que crear un servicio es como crear una función de constructor (clase OO) de la cual podemos crear una instancia usando una nueva palabra clave. Lo único que debe notar aquí es que cuando usamos el método de Servicio para crear servicios, creará automáticamente una instancia del mismo utilizando un mecanismo de inyección de dependencia compatible con AngularJS
fuente