Pelo que entendi, quando dentro de uma fábrica eu retorno um objeto que é injetado em um controlador. Quando estou dentro de um serviço, estou lidando com o objeto usando this
e não retornando nada.
Eu assumi que um serviço sempre foi um singleton e que um novo objeto de fábrica é injetado em todos os controladores. No entanto, como se vê, um objeto de fábrica também é um singleton?
Código de exemplo para demonstrar:
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;
});
Ao mudar user.first
em ACtrl
verifica-se que user.first
em BCtrl
também é alterado, por exemplo, User
é um singleton?
Minha suposição era que uma nova instância foi injetada em um controlador com uma fábrica?
Respostas:
Todos os serviços angulares são singletons :
Documentos (consulte Serviços como singletons ): https://docs.angularjs.org/guide/services
Basicamente, a diferença entre o serviço e a fábrica é a seguinte:
Confira esta apresentação sobre $ deliver: http://slides.wesalvaro.com/20121113/#/
Esses slides foram usados em um dos encontros do AngularJs: http://blog.angularjs.org/2012/11/more-angularjs-meetup-videos.html
fonte
new
-lo.Para mim, a revelação veio quando percebi que todos eles funcionam da mesma maneira: executando algo uma vez , armazenando o valor que recebem e depois tossindo esse mesmo valor armazenado quando referenciado por meio da Injeção de Dependência.
Digamos que temos:
A diferença entre os três é que:
a
O valor armazenado de vem da execuçãofn
, em outras palavras:fn()
b
O valor armazenado de vem denew
ingfn
, em outras palavras:new fn()
c
O valor armazenado é obtido primeiro pela obtenção de uma instâncianew
ingfn
e, em seguida, pela execução de um$get
método da instânciao que significa que há algo como um objeto de cache dentro do angular, cujo valor de cada injeção é atribuído apenas uma vez, quando foram injetados pela primeira vez e onde:
É por isso que usamos
this
em serviços e definimos umthis.$get
em provedores.Espero que isto ajude.
fonte
exemplo ao vivo
exemplo "olá mundo"
com
factory
/service
/provider
:fonte
Também existe uma maneira de retornar uma função construtora para que você possa retornar classes renováveis em fábricas, como este:
Então você pode fazer isso em um controlador, que usa MyObjectWithParam:
Veja aqui o exemplo completo:
http://plnkr.co/edit/GKnhIN?p=preview
E aqui as páginas do grupo do Google, onde foram discutidas:
https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/b8hdPskxZXsJ
fonte
App.factory('MyObjectWithParam', ['$injector', function ($injector) { return function(name) { return $injector.instantiate(MyObjectWithParam,{ name: name }); }; }]);
Leia mais sobre isso aqui: docs.angularjs.org/tutorial/step_05.service
?.factory
em oposição a.service
?new Car('BMW')
enew Car('Ford')
e eles não compartilham as mesmas variáveis e tudo.Aqui estão as principais diferenças:
Serviços
Sintaxe:
module.service( 'serviceName', function );
Resultado: ao declarar serviceName como um argumento injetável, você receberá a instância de uma função passada para
module.service
.Uso: Pode ser útil para compartilhar funções utilitárias que são úteis para chamar, simplesmente anexando () à referência da função injetada. Também pode ser executado com
injectedArg.call( this )
ou similar.Fábricas
Sintaxe:
module.factory( 'factoryName', function );
Resultado: ao declarar factoryName como um argumento injetável, você receberá o valor retornado invocando a referência de função passada para
module.factory
.Uso: Pode ser útil para retornar uma função 'class' que pode ser renovada para criar instâncias.
Verifique também a documentação do AngularJS e uma pergunta semelhante sobre o stackoverflow confusa sobre serviço x fábrica .
Aqui está um exemplo usando serviços e fábrica . Leia mais sobre o serviço AngularJS x fábrica .
fonte
Somando-se à primeira resposta, acho que .service () é para pessoas que escreveram seu código em um estilo mais orientado a objetos (C # / Java) (usando essa palavra-chave e instanciando o objeto por meio da função prototype / Constructor).
O Factory é para desenvolvedores que escrevem código mais natural ao estilo de codificação javascript / funcional.
Veja o código-fonte do método .service e .factory no angular.js - todos eles internamente chamam o método do provedor:
fonte
Muito simplesmente:
.service - a função registrada será invocada como construtor (também conhecido como 'newed')
.factory - a função registrada será chamada como uma função simples
Ambos são invocados uma vez, resultando em um objeto singleton que é injetado em outros componentes do seu aplicativo.
fonte
Todos os provedores funcionam da mesma maneira. Os diferentes métodos
service
,factory
,provider
apenas deixá-lo fazer a mesma coisa em menos código.PS Há também
value
econstant
.Cada caso especial ao longo da cadeia, começando com
provider
e terminando com,value
tem uma limitação adicional. Portanto, para decidir entre eles, você deve se perguntar o que permite realizar o que deseja com menos código.Aqui está uma imagem que mostra o que quero dizer:
Você pode obter um guia de detalhamento e referência no post em que obtive esta imagem:
http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
fonte
console.log()
e injetando em vários controladores.Aqui estão mais alguns exemplos de serviços versus fábricas que podem ser úteis para ver a diferença entre eles. Basicamente, um serviço tem "novo ..." chamado, ele já é instanciado. Uma fábrica não é instanciada automaticamente.
Exemplos básicos
Retornar um objeto de classe que possui um único método
Aqui está um serviço que possui um único método:
Aqui está uma fábrica que retorna um objeto com um método:
Retornar um valor
Uma fábrica que retorna uma lista de números:
Um serviço que retorna uma lista de números:
A saída em ambos os casos é a mesma, a lista de números.
Exemplos avançados
Variáveis de "classe" usando fábricas
Neste exemplo, definimos um CounterFactory, ele aumenta ou diminui um contador e você pode obter a contagem atual ou quantos objetos CounterFactory foram criados:
Usamos o
CounterFactory
para criar vários contadores. Podemos acessar a variável de classe para ver quantos contadores foram criados:A saída deste código é:
fonte
“Fábrica” e “Serviço” são diferentes maneiras de executar DI (injeção de dependência) em angular.
Então, quando definimos o DI usando "service", como mostrado no código abaixo. Isso cria uma nova instância GLOBAL do objeto "Logger" e a injeta na função.
Quando você define o DI usando uma "fábrica", ele não cria uma instância. Apenas passa o método e, posteriormente, o consumidor internamente precisa fazer chamadas para a fábrica em busca de instâncias de objetos.
Abaixo está uma imagem simples que mostra visualmente como o processo de DI para "Serviço" é diferente de "Fábrica".
Fábrica deve ser usada Quando queremos criar diferentes tipos de objetos, dependendo dos cenários. Por exemplo, dependendo do cenário, queremos criar um objeto "Cliente" simples, ou "Cliente" com o objeto "Endereço" ou "Cliente" com o objeto "Telefone". Aqui está uma explicação detalhada deste parágrafo
O serviço deve ser usado Quando temos utilidade ou funções compartilhadas a serem injetadas, como Utility, Logger, Error handler etc.
fonte
Estilo de serviço : ( provavelmente o mais simples ) retorna a função real: Útil para compartilhar funções utilitárias que são úteis para chamar, simplesmente anexando () à referência da função injetada.
Um serviço no AngularJS é um objeto JavaScript singleton que contém um conjunto de funções
Estilo de fábrica : ( mais envolvido, mas mais sofisticado ) retorna o valor de retorno da função: instancia um objeto como new Object () em java.
Factory é uma função que cria valores. Quando um serviço, controlador etc. precisa de um valor injetado de uma fábrica, a fábrica cria o valor sob demanda. Uma vez criado, o valor é reutilizado para todos os serviços, controladores etc. que precisam dele injetado.
Estilo do provedor : ( versão configurável completa ) retorna a saída da função $ get da função: Configurável.
Os fornecedores no AngularJS são a forma mais flexível de fábrica que você pode criar. Você registra um provedor com um módulo, exatamente como em um serviço ou fábrica, exceto pelo uso da função provider ().
src jenkov
jsbin
jsfiddle
fonte
A diferença básica é que o provedor permite definir valores primitivos (não-objetos), matriz ou função de retorno de chamada na variável declarada de fábrica e, portanto, se você retornar um objeto, ele deverá ser explicitamente declarado e retornado.
Por outro lado, um serviço só pode ser usado para definir a variável declarada de serviço como um objeto, portanto, podemos evitar a criação explícita e o retorno dos objetos, enquanto, por outro lado, permite o uso da palavra - chave this .
Ou, em poucas palavras, " provedor é uma forma mais genérica, enquanto o serviço é limitado apenas a objetos".
fonte
Foi assim que entendi a diferença entre eles em termos de padrões de design:
Serviço : retorne um tipo que será renovado para criar um objeto desse tipo. Se a analogia Java for usada, o Serviço retornará uma definição de Classe Java .
Fábrica : retorna um objeto concreto que pode ser usado imediatamente. Na analogia Java, uma fábrica retorna um objeto Java .
A parte que muitas vezes confunde as pessoas (inclusive eu) é que, quando você injeta um Serviço ou uma Fábrica no seu código, elas podem ser usadas da mesma maneira, o que você obtém no seu código nos dois casos é um objeto concreto que você pode chamar imediatamente. O que significa que, no caso do Serviço, chamadas angulares "novas" na declaração de serviço em seu nome. Eu acho que esse é um conceito complicado.
fonte
Essa seria a melhor e curta resposta para entender o serviço versus fornecedor de fábrica
Fonte : https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/HuZsOsMvKv4J
Aqui o que ben diz com uma demonstração http://jsbin.com/ohamub/1/edit?html,output
"Existem comentários no código que ilustram as principais diferenças, mas vou expandi-las um pouco aqui. Como observação, estou apenas tentando entender isso, então, se disser algo errado, entre em contato.
Serviços
Sintaxe : module.service ('serviceName', função);
Resultado : ao declarar serviceName como um argumento injetável, você receberá a referência real da função passada para module.service.
Uso : Pode ser útil para compartilhar funções utilitárias que são úteis para chamar, simplesmente anexando () à referência da função injetada. Também pode ser executado com injectedArg.call (this) ou similar.
Fábricas
Sintaxe : module.factory ('factoryName', função);
Resultado : ao declarar factoryName como um argumento injetável, você receberá o valor retornado invocando a referência de função passada para module.factory.
Uso : Pode ser útil para retornar uma função 'class' que pode ser renovada para criar instâncias.
Fornecedores
Sintaxe : module.provider ('providerName', função);
Resultado : ao declarar providerName como um argumento injetável, você receberá o valor retornado invocando o método $ get da referência de função passada para module.provider.
Uso : Pode ser útil para retornar uma função de 'classe' que pode ser nova para criar instâncias, mas que requer algum tipo de configuração antes de ser injetada. Talvez útil para classes reutilizáveis em projetos? Ainda meio nebuloso neste. "Ben
fonte
Eu tive essa confusão por um tempo e estou tentando o meu melhor para fornecer uma explicação simples aqui. Espero que isso ajude!
angular .factory
eangular .service
ambos são usados para inicializar um serviço e trabalhar da mesma maneira.A única diferença é como você deseja inicializar seu serviço.
Ambos são singletons
Fábrica
app.factory (
<service name>
,<function with a return value>
)Se você deseja inicializar seu serviço a partir de uma função que possui um valor de retorno , use este
factory
método.por exemplo
Ao injetar este serviço (por exemplo, no seu controlador):
myService()
) para retornar o objetoServiço
app.service (
<service name>
,<constructor function>
)Se você deseja inicializar seu serviço a partir de uma função construtora (usando a
this
palavra-chave), use esteservice
método.por exemplo
Ao injetar este serviço (por exemplo, no seu controlador):
new
sua função (asnew myService()
) retorne o objetoNOTA: Se você usar
factory
com<constructor function>
ouservice
com<function with a return value>
, ele não funcionará.Exemplos - DEMOs
fonte
Foi isso que me ajudou a entender a diferença, graças a um post de Pascal Precht.
Um serviço é um método em um módulo que leva um nome e uma função que define o serviço. Você pode injetar e usar esse serviço específico em outros componentes, como controladores, diretivas e filtros. Uma fábrica é um método em um módulo e também leva um nome e uma função, que define a fábrica. Também podemos injetar e usar da mesma maneira que fizemos com o serviço.
Os objetos criados com o novo usam o valor da propriedade prototype de sua função construtora como protótipo; portanto, encontrei o código Angular que chama Object.create (), que acredito ser a função construtora de serviço quando é instanciada. No entanto, uma função de fábrica é realmente apenas uma função que é chamada, e é por isso que precisamos retornar um objeto literal para a fábrica.
Aqui está o código angular 1.5 que encontrei para a fábrica:
Fragmento de código-fonte angular para a função factory ():
Ele pega o nome e a função de fábrica que é passada e retorna um provedor com o mesmo nome, que possui um método $ get, que é a nossa função de fábrica. Sempre que você solicita ao injetor uma dependência específica, ele basicamente solicita ao provedor correspondente uma instância desse serviço, chamando o método $ get (). É por isso que $ get () é necessário ao criar provedores.
Aqui está o código angular 1.5 para serviço.
Acontece que quando chamamos service (), na verdade, chama factory ()! No entanto, ele não apenas passa nossa função de construtor de serviço para a fábrica como está. Ele também passa uma função que solicita ao injetor que instancia um objeto pelo construtor especificado.
Em outras palavras, se injetarmos o MyService em algum lugar, o que acontece no código é:
Para reajustá-lo novamente, um serviço chama uma fábrica, que é um método $ get () no provedor correspondente. Além disso, $ injector.instantiate () é o método que finalmente chama Object.create () com a função construtora. É por isso que usamos "isso" nos serviços.
Para o ES5, não importa qual seja o uso: service () ou factory (), é sempre uma fábrica chamada que cria um provedor para o nosso serviço.
Você pode fazer exatamente a mesma coisa com os serviços também. Um serviço é uma função construtora, no entanto, que não nos impede de retornar literais de objetos. Assim, podemos pegar nosso código de serviço e escrevê-lo de uma maneira que basicamente faz exatamente a mesma coisa que nossa fábrica ou, em outras palavras, você pode escrever um serviço como fábrica para retornar um objeto.
Por que a maioria das pessoas recomenda usar fábricas em vez de serviços? Esta é a melhor resposta que eu vi que vem do livro de Pawel Kozlowski: Mastering Web Application Development with AngularJS.
fonte
this
palavra-chave para definir a função.$get
você define e pode ser usado para obter o objeto que retorna os dados.fonte
Existem três maneiras de lidar com a lógica de negócios no AngularJS: ( Inspirado no curso Coursera AngularJS de Yaakov ):
Aqui vamos falar apenas sobre Serviço x Fábrica
SERVIÇO :
Sintaxe:
app.js
index.html
Os principais recursos do serviço:
Instanciado preguiçosamente : se o serviço não for injetado, ele nunca será instanciado. Então, para usá-lo, você precisará injetá-lo em um módulo.
Singleton : se for injetado em vários módulos, todos terão acesso a apenas uma instância específica. Por isso, é muito conveniente compartilhar dados entre diferentes controladores.
FÁBRICA
Agora vamos falar sobre a fábrica no AngularJS
Primeiro, vamos dar uma olhada na sintaxe :
app.js :
Agora, usando os dois acima no controlador:
Características da fábrica:
Esses tipos de serviços seguem o padrão de design da fábrica . A fábrica pode ser pensada como um local central que cria novos objetos ou métodos.
Isso não produz apenas singleton, mas também serviços personalizáveis.
O
.service()
método é uma fábrica que sempre produz o mesmo tipo de serviço, que é um singleton. Não há uma maneira fácil de configurar seu comportamento. Esse.service()
método é geralmente usado como um atalho para algo que não requer nenhuma configuração.fonte
Para explicações curtas e simples, consulte https://stackoverflow.com/a/26924234/5811973 .
Para explicação detalhada, consulte https://stackoverflow.com/a/15666049/5811973 .
Também da documentação do angularJs:
fonte
Você pode entender a diferença com esta analogia - considere a diferença entre uma função normal que retornará algum valor e a função construtora que será instanciada usando a nova palavra-chave. um objeto), ao passo que criar serviço é como criar função construtora (classe OO), da qual podemos criar instância usando a nova palavra-chave. A única coisa a notar é que, quando usamos o método Service para criar serviços, ele automaticamente cria uma instância usando o mecanismo de injeção de dependência suportado pelo AngularJS
fonte