Eu descobri que todos os termos angulares eram intimidadores para iniciantes. Começamos com esta folha de dicas que era um pouco mais fácil para nossos programadores entenderem enquanto aprendíamos o Angular demisx.github.io/angularjs/2014/09/14/… . Espero que isso ajude sua equipe também.
Demisx
7
Na minha opinião, a melhor maneira de entender a diferença é usar a documentação da Angular: docs.angularjs.org/guide/providers , é extremamente bem explicada e usa um exemplo peculiar para ajudá-lo a entendê-la.
Rafael Merlin
3
@ Blaise Obrigado! De acordo com meu comentário no post, deixei de fora intencionalmente, pois 99% dos casos de uso da minha experiência podem ser tratados com êxito via service.factory. Não queria complicar ainda mais esse assunto.
Na lista de discussão do AngularJS, recebi uma discussão incrível que explica serviço x fábrica x provedor e seu uso de injeção. Compilando as respostas:
Serviços
Sintaxe: module.service( 'serviceName', function );
Resultado: Ao declarar serviceName como um argumento injetável, você receberá uma instância da função. Em outras palavrasnew FunctionYouPassedToService() .
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 .
Fornecedores
Sintaxe: module.provider( 'providerName', function );
Resultado: Ao declarar providerName como um argumento injetável, você será fornecido(new ProviderFunction()).$get() . A função construtora é instanciada antes que o método $ get seja chamado - ProviderFunctioné a referência da função passada para module.provider.
Os fornecedores têm a vantagem de poderem ser configurados durante a fase de configuração do módulo.
Este exemplo poderia ser incrível se usasse um exemplo prático claro. Eu me perco tentando descobrir o que o ponto de coisas como toEquale greeter.Greeté. Por que não usar algo um pouco mais real e relacionável?
precisa saber é o seguinte
5
Usar a função expect () é uma má escolha para explicar algo. Use o código do mundo real da próxima vez.
Exemplo "Olá, mundo", com factory/ service/ provider:
var myApp = angular.module('myApp',[]);//service style, probably the simplest one
myApp.service('helloWorldFromService',function(){this.sayHello =function(){return"Hello, World!";};});//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory',function(){return{
sayHello:function(){return"Hello, World!";}};});//provider style, full blown, configurable version
myApp.provider('helloWorld',function(){this.name ='Default';this.$get =function(){var name =this.name;return{
sayHello:function(){return"Hello, "+ name +"!";}}};this.setName =function(name){this.name = name;};});//hey, we can configure a provider!
myApp.config(function(helloWorldProvider){
helloWorldProvider.setName('World');});functionMyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService){
$scope.hellos =[
helloWorld.sayHello(),
helloWorldFromFactory.sayHello(),
helloWorldFromService.sayHello()];}
Não thismuda o contexto na $getfunção? - você não se refere mais ao provedor instanciado nessa função.
Nate-Wilkins
12
@ Nate: thisnão muda o contexto, na verdade, porque o que está sendo chamado é new Provider(). $ Get (), para onde Providera função está sendo passada app.provider. Ou seja, $get()está sendo chamado como método no construído Provider, portanto, thisserá referido Providercomo o exemplo sugere.
Brandon
1
@Brandon Ohh ok, isso é legal, então. Confuso à primeira vista - obrigado pelo esclarecimento!
Nate-Wilkins
3
Por que recebo Unknown provider: helloWorldProvider <- helloWorldao executar isso localmente? Comentando, o mesmo erro para os outros 2 exemplos. Existe alguma configuração de provedor oculto? (Angular 1.0.8) - Encontrado: stackoverflow.com/questions/12339272/…
Antoine
4
É o motivo pelo qual @Antoine obtém o erro "Fornecimento desconhecido: helloWorldProvider" porque no seu código .config você usa 'helloWorldProvider', mas quando define o provedor em myApp.provider ('helloWorld', function ()), usa 'Olá Mundo'? Em outras palavras, no seu código de configuração, como a angular sabe que você está se referindo ao provedor helloWorld? Obrigado
jmtoung
645
TL; DR
1) Ao usar um Factory, você cria um objeto, adiciona propriedades a ele e retorna o mesmo objeto. Quando você passar esta fábrica para o seu controlador, essas propriedades no objeto estarão agora disponíveis nesse controlador através da sua fábrica.
2) Ao usar o Serviço , o AngularJS o instancia nos bastidores com a palavra-chave 'new'. Por isso, você adicionará propriedades a 'this' e o serviço retornará 'this'. Quando você passa o serviço para o seu controlador, essas propriedades agora estarão disponíveis nesse controlador através do seu serviço.
3) Os provedores são o único serviço que você pode transmitir para a função .config (). Use um provedor quando desejar fornecer configuração em todo o módulo para seu objeto de serviço antes de disponibilizá-lo.
app.controller(‘myProvider’,function($scope, myProvider){
$scope.artist = myProvider.getArtist();
$scope.data.thingFromConfig = myProvider.thingOnConfig;});
app.provider(‘myProvider’,function(){//Only the next two lines are available in the app.config()this._artist =‘’;this.thingFromConfig =‘’;this.$get =function(){var that =this;return{
getArtist:function(){return that._artist;},
thingOnConfig: that.thingFromConfig
}}});
app.config(function(myProviderProvider){
myProviderProvider.thingFromConfig =‘This was setin config’;});
Não TL; DR
1)
Fábricas de fábrica são a maneira mais popular de criar e configurar um serviço. Realmente não há muito mais do que o TL; DR disse. Você acabou de criar um objeto, adicionar propriedades a ele e retornar o mesmo objeto. Então, quando você passar a fábrica para o seu controlador, essas propriedades no objeto estarão agora disponíveis nesse controlador através da sua fábrica. Um exemplo mais extenso está abaixo.
app.factory(‘myFactory’,function(){var service ={};return service;});
Agora, quaisquer propriedades que anexarmos a 'service' estarão disponíveis quando passarmos 'myFactory' para o nosso controlador.
Agora vamos adicionar algumas variáveis 'privadas' à nossa função de retorno de chamada. Eles não estarão diretamente acessíveis no controlador, mas, eventualmente, configuraremos alguns métodos getter / setter no 'service' para poder alterar essas variáveis 'privadas' quando necessário.
Aqui você notará que não estamos anexando essas variáveis / funções ao 'serviço'. Estamos simplesmente criando-os para usá-los ou modificá-los posteriormente.
baseUrl é o URL base que a API do iTunes requer
_artist é o artista que queremos pesquisar
_finalUrl é o URL final e totalmente construído para o qual faremos a chamada para o iTunes
makeUrl é uma função que criará e retornará nossa URL amigável do iTunes.
Agora que nossas variáveis e funções auxiliares / particulares estão em vigor, vamos adicionar algumas propriedades ao objeto 'service'. Tudo o que colocamos em 'serviço' pode ser usado diretamente dentro de qualquer controlador no qual passamos 'myFactory'.
Vamos criar métodos setArtist e getArtist que simplesmente retornam ou definem o artista. Também vamos criar um método que chamará a API do iTunes com nosso URL criado. Esse método retornará uma promessa que será cumprida assim que os dados voltarem da API do iTunes. Se você não teve muita experiência no uso de promessas no AngularJS, recomendo fazer um mergulho profundo nelas.
Abaixo, o setArtist aceita um artista e permite que você o defina. O getArtist retorna o artista. O callItunes chama primeiro makeUrl () para criar o URL que usaremos com nossa solicitação $ http. Em seguida, ele configura um objeto de promessa, faz uma solicitação $ http com nosso URL final e, como $ http retorna uma promessa, podemos chamar .success ou .error após nossa solicitação. Em seguida, resolvemos nossa promessa com os dados do iTunes ou a rejeitamos com uma mensagem dizendo 'Houve um erro'.
Agora nossa fábrica está completa. Agora podemos injetar 'myFactory' em qualquer controlador e, em seguida, poderemos chamar nossos métodos que anexamos ao nosso objeto de serviço (setArtist, getArtist e callItunes).
No controlador acima, estamos injetando no serviço 'myFactory'. Em seguida, definimos propriedades em nosso objeto $ scope com dados de 'myFactory'. O único código complicado acima é se você nunca lidou com promessas antes. Como o callItunes está retornando uma promessa, podemos usar o método .then () e definir apenas $ scope.data.artistData quando nossa promessa for cumprida com os dados do iTunes. Você notará que nosso controlador é muito 'fino' (esta é uma boa prática de codificação). Todos os nossos dados lógicos e persistentes estão localizados em nosso serviço, não em nosso controlador.
2) Serviço
Talvez a maior coisa a saber quando se lida com a criação de um Serviço é que ele é instanciado com a palavra-chave 'new'. Para os gurus do JavaScript, isso deve fornecer uma grande dica sobre a natureza do código. Para aqueles com conhecimentos limitados em JavaScript ou para aqueles que não conhecem muito bem o que a palavra-chave 'new' realmente faz, vamos revisar alguns fundamentos do JavaScript que eventualmente nos ajudarão a entender a natureza de um Serviço.
Para realmente ver as alterações que ocorrem quando você invoca uma função com a palavra-chave 'new', vamos criar uma função e invocá-la com a palavra-chave 'new', depois vamos mostrar o que o intérprete faz quando vê a palavra-chave 'new'. Os resultados finais serão os mesmos.
Essa é uma função típica do construtor JavaScript. Agora, sempre que invocarmos a função Pessoa usando a palavra-chave 'new', 'this' será vinculado ao objeto recém-criado.
Agora, vamos adicionar um método ao protótipo de nossa Person, para que fique disponível em todas as instâncias da nossa classe de Person.
Person.prototype.sayName =function(){
alert(‘My name is‘+this.name);}
Agora, como colocamos a função sayName no protótipo, todas as instâncias de Person poderão chamar a função sayName para alertar o nome dessa instância.
Agora que temos nossa função construtora Person e nossa função sayName em seu protótipo, vamos criar uma instância de Person e chamar a função sayName.
var tyler =newPerson(‘Tyler’,23);
tyler.sayName();//alerts ‘My name is Tyler’
Portanto, todo o código para criar um construtor Person, adicionar uma função a seu protótipo, criar uma instância Person e chamar a função em seu protótipo se parece com isso.
varPerson=function(name, age){this.name = name;this.age = age;}Person.prototype.sayName =function(){
alert(‘My name is‘+this.name);}var tyler =newPerson(‘Tyler’,23);
tyler.sayName();//alerts ‘My name is Tyler’
Agora, vamos ver o que realmente está acontecendo quando você usa a palavra-chave 'new' em JavaScript. A primeira coisa que você deve notar é que, depois de usar 'new' em nosso exemplo, podemos chamar um método (sayName) em 'tyler' como se fosse um objeto - é porque é. Então, primeiro, sabemos que nosso construtor Person está retornando um objeto, se podemos ver isso no código ou não. Segundo, sabemos que, como nossa função sayName está localizada no protótipo e não diretamente na instância Person, o objeto que a função Person está retornando deve delegar ao seu protótipo em pesquisas com falha. Em termos mais simples, quando chamamos tyler.sayName (), o intérprete diz: “OK, vou olhar para o objeto 'tyler' que acabamos de criar, localize a função sayName e chame-a. Espere um minuto, não o vejo aqui - tudo o que vejo é nome e idade, deixe-me verificar o protótipo. Sim, parece que está no protótipo, deixe-me chamá-lo. ”.
Abaixo está o código de como você pode pensar sobre o que a palavra-chave 'nova' está realmente fazendo em JavaScript. É basicamente um exemplo de código do parágrafo acima. Coloquei a 'visão do intérprete' ou a maneira como o intérprete vê o código dentro das notas.
varPerson=function(name, age){//The below line creates an object(obj) that will delegate to the person’s prototype on failed lookups.//var obj = Object.create(Person.prototype);//The line directly below this sets ‘this’ to the newly created object//this = obj;this.name = name;this.age = age;//return this;}
Agora, tendo esse conhecimento do que a palavra-chave 'new' realmente faz em JavaScript, a criação de um Serviço no AngularJS deve ser mais fácil de entender.
A principal coisa a entender ao criar um Serviço é saber que os Serviços são instanciados com a palavra-chave 'new'. Combinando esse conhecimento com nossos exemplos acima, você deve reconhecer agora que anexará suas propriedades e métodos diretamente a 'this', que serão devolvidos pelo próprio Serviço. Vamos dar uma olhada nisso em ação.
Diferentemente do que fizemos originalmente com o exemplo do Factory, não precisamos criar um objeto e, em seguida, retorná-lo, porque, como mencionado muitas vezes antes, usamos a palavra-chave 'new' para que o intérprete crie esse objeto, faça-o delegar para é protótipo e, em seguida, devolva-o para nós sem que tenhamos que fazer o trabalho.
Primeiramente, vamos criar nossa função 'privada' e auxiliar. Isso deve parecer muito familiar, já que fizemos exatamente a mesma coisa com nossa fábrica. Não vou explicar o que cada linha faz aqui, porque fiz isso no exemplo de fábrica; se você estiver confuso, releia o exemplo de fábrica.
Agora, assim como em nossa fábrica, setArtist, getArtist e callItunes estarão disponíveis em qualquer controlador em que passarmos o myService. Aqui está o controlador myService (que é quase exatamente o mesmo que o nosso controlador de fábrica).
Como mencionei antes, quando você realmente entende o que 'novo' faz, os Serviços são quase idênticos às fábricas no AngularJS.
3) Fornecedor
A principal coisa a lembrar sobre os Provedores é que eles são o único serviço que você pode passar para a parte app.config do seu aplicativo. Isso é de grande importância se você precisar alterar parte do objeto de serviço antes que ele esteja disponível em qualquer outro lugar do aplicativo. Embora muito parecido com Serviços / Fábricas, existem algumas diferenças que discutiremos.
Primeiro, configuramos nosso provedor de maneira semelhante ao nosso serviço e fábrica. As variáveis abaixo são nossa função 'privada' e auxiliar.
app.provider('myProvider',function(){var baseUrl ='https://itunes.apple.com/search?term=';var _artist ='';var _finalUrl ='';//Going to set this property on the config function below.this.thingFromConfig =‘’;var makeUrl =function(){
_artist = _artist.split(' ').join('+');
_finalUrl = baseUrl + _artist +'&callback=JSON_CALLBACK'return _finalUrl;}}
* Novamente, se qualquer parte do código acima estiver confusa, consulte a seção Factory, onde explico o que isso faz com mais detalhes.
Você pode pensar em Provedores como tendo três seções. A primeira seção são as variáveis / funções 'particulares' que serão modificadas / definidas posteriormente (mostradas acima). A segunda seção são as variáveis / funções que estarão disponíveis na função app.config e, portanto, estão disponíveis para alteração antes de estarem disponíveis em qualquer outro lugar (também mostrado acima). É importante observar que essas variáveis precisam ser anexadas à palavra-chave 'this'. No nosso exemplo, apenas 'thingFromConfig' estará disponível para alteração no app.config. A terceira seção (mostrada abaixo) são todas as variáveis / funções que estarão disponíveis no seu controlador quando você passar o serviço 'myProvider' para esse controlador específico.
Ao criar um serviço com o Provedor, as únicas propriedades / métodos que estarão disponíveis no seu controlador são as propriedades / métodos retornados da função $ get (). O código abaixo coloca $ get on 'this' (que sabemos que eventualmente serão retornados dessa função). Agora, essa função $ get retorna todos os métodos / propriedades que queremos que estejam disponíveis no controlador. Aqui está um exemplo de código.
Agora, o código completo do provedor se parece com isso
app.provider('myProvider',function(){var baseUrl ='https://itunes.apple.com/search?term=';var _artist ='';var _finalUrl ='';//Going to set this property on the config function belowthis.thingFromConfig ='';var makeUrl =function(){
_artist = _artist.split(' ').join('+');
_finalUrl = baseUrl + _artist +'&callback=JSON_CALLBACK'return _finalUrl;}this.$get =function($http, $q){return{
callItunes:function(){
makeUrl();var deferred = $q.defer();
$http({
method:'JSONP',
url: _finalUrl
}).success(function(data){
deferred.resolve(data);}).error(function(){
deferred.reject('There was an error')})return deferred.promise;},
setArtist:function(artist){
_artist = artist;},
getArtist:function(){return _artist;},
thingOnConfig:this.thingFromConfig
}}});
Agora, assim como em nossa fábrica e Serviço, setArtist, getArtist e callItunes estarão disponíveis em qualquer controlador em que passarmos o myProvider. Aqui está o controlador myProvider (que é quase exatamente o mesmo que o nosso controlador de fábrica / serviço).
Como mencionado anteriormente, o objetivo principal de criar um serviço com o Provedor é poder alterar algumas variáveis por meio da função app.config antes que o objeto final seja passado para o restante do aplicativo. Vamos ver um exemplo disso.
app.config(function(myProviderProvider){//Providers are the only service you can pass into app.config
myProviderProvider.thingFromConfig ='This sentence was set in app.config. Providers are the only service that can be passed into config. Check out the code to see how it works';});
Agora você pode ver como 'thingFromConfig' é uma string vazia no nosso provedor, mas quando isso aparecer no DOM, será 'Esta frase foi configurada ...'.
A única parte que falta nessa excelente redação é as vantagens relativas de usar o serviço em uma fábrica; que é claramente explicado na resposta aceita por Lior
O punchline dos 'gurus do JavaScript' era astuto. : Eu acho que essa resposta esclarece muito as coisas. Soberbamente escrito.
amarmishra
4
Seu TLDR precisa de um TLDR.
JensB
3
@JensB tl; dr - Aprenda a reagir.
Tyler McGinnis
512
Todos os serviços são singletons ; eles são instanciados uma vez por aplicativo. Eles podem ser de qualquer tipo , seja um primitivo, literal de objeto, função ou até uma instância de um tipo personalizado.
O value,factory , service, constant, e providermétodos são todos os provedores. Eles ensinam ao Injetor como instanciar os Serviços.
A mais detalhada, mas também a mais abrangente, é uma receita de Provedor. Os quatro restantes tipos de receita - Valor, Fábrica, Serviço e Constante - são apenas açúcar sintático em cima de uma receita de provedor .
o receita do valor é o caso mais simples, em que você instancia o serviço e fornece o valor instanciado ao injetor.
o receita de fábrica fornece ao injetor uma função de fábrica que ele chama quando precisa instanciar o serviço. Quando chamada, a função de fábrica cria e retorna a instância de serviço. As dependências do Serviço são injetadas como argumentos das funções. Então, usar esta receita adiciona as seguintes habilidades:
Capacidade de usar outros serviços (ter dependências)
Inicialização de serviço
Inicialização atrasada / lenta
A receita de serviço é quase a mesma que a receita de fábrica, mas aqui o Injector chama um construtor com o novo operador, em vez de uma função de fábrica.
A receita do provedor geralmente é um exagero . Ele adiciona mais uma camada de indireção, permitindo que você configure a criação da fábrica.
Você deve usar a receita do provedor apenas quando quiser expor uma API para a configuração de todo o aplicativo que deve ser feita antes do aplicativo ser iniciado. Isso geralmente é interessante apenas para serviços reutilizáveis cujo comportamento pode precisar variar um pouco entre aplicativos.
A receita Constant é exatamente como a receita Value, exceto que permite definir serviços disponíveis na configuração fase de . Antes dos serviços criados usando a receita Value. Ao contrário de Valores, eles não podem ser decorados usando decorator.
Então serviço e fábrica são essencialmente os mesmos? Usar um dos outros fornece nada além de sintaxe alternativa?
Matt
2
@ Matt, sim, serviço é uma maneira concisa quando você já tem sua própria função que deseja expor como serviço. De documentos: myApp.factory ('unicornLauncher', ["apiToken", função (apiToken) {retorna novo UnicornLauncher (apiToken);}]); vs: myApp.service ('unicornLauncher', ["apiToken", UnicornLauncher]);
janek
5
@joshperry Como novato, pesquisei a diferença entre serviço e fábrica por um tempo. Concordo que esta é a melhor resposta de sempre! Eu entenderia serviço como uma classe de serviço (por exemplo, classe codificador / decodificador), que pode ter algumas propriedades particulares. E a fábrica fornece um conjunto de métodos auxiliares sem estado.
stanleyxu2005
3
Os exemplos da Yaa em outras respostas acima falham em explicar muito claramente a diferença principal em relação aos serviços e fornecedores, que é injetada no momento em que essas receitas são instanciadas.
precisa
223
Compreendendo o AngularJS Factory, Service and Provider
Tudo isso é usado para compartilhar objetos singleton reutilizáveis. Ajuda a compartilhar código reutilizável em seu aplicativo / vários componentes / módulos.
Instanciado preguiçosamente - o Angular apenas instancia um serviço / fábrica quando um componente de aplicativo depende dele.
Singletons - Cada componente dependente de um serviço obtém uma referência à instância única gerada pela fábrica de serviços.
Fábrica
Uma fábrica é uma função na qual você pode manipular / adicionar lógica antes de criar um objeto, para que o objeto recém-criado seja retornado.
app.factory('MyFactory',function(){var serviceObj ={};//creating an object with methods/functions or variables
serviceObj.myFunction =function(){//TO DO:};//return that objectreturn serviceObj;});
Uso
Pode ser apenas uma coleção de funções como uma classe. Portanto, ele pode ser instanciado em diferentes controladores quando você o injeta nas funções de controlador / fábrica / diretiva. É instanciado apenas uma vez por aplicativo.
Serviço
Simplesmente enquanto olha para os serviços, pense no protótipo da matriz. Um serviço é uma função que instancia um novo objeto usando a palavra-chave 'new'. Você pode adicionar propriedades e funções a um objeto de serviço usando a thispalavra - chave Ao contrário de uma fábrica, ele não retorna nada (retorna um objeto que contém métodos / propriedades).
app.service('MyService',function(){//directly binding events to this contextthis.myServiceFunction =function(){//TO DO:};});
Uso
Use-o quando precisar compartilhar um único objeto em todo o aplicativo. Por exemplo, detalhes do usuário autenticado, métodos / dados compartilhados, funções do utilitário etc.
Fornecedor
Um provedor é usado para criar um objeto de serviço configurável. Você pode definir a configuração de serviço na função de configuração. Retorna um valor usando a $get()função A $getfunção é executada na fase de execução em angular.
app.provider('configurableService',function(){var name ='';//this method can be be available at configuration time inside app.config.this.setName =function(newName){
name = newName;};this.$get =function(){var getName =function(){return name;};return{
getName: getName //exposed object to where it gets injected.};};});
Uso
Quando você precisar fornecer configuração em módulo para o seu objeto de serviço antes de disponibilizá-lo, por exemplo. suponha que você queira definir o URL da API com base no seu ambiente dev, como , stageouprod
NOTA
Somente o provedor estará disponível na fase de configuração angular, enquanto o serviço e a fábrica não estiverem.
Espero que isso tenha esclarecido sua compreensão sobre a fábrica, o serviço e o fornecedor .
O que eu faria se quisesse ter um serviço com uma interface específica, mas ter duas implementações diferentes e injetar cada uma em um controlador, mas vinculado a estados diferentes usando o ui-router? por exemplo, faça chamadas remotas em um estado, mas grave no armazenamento local em outro. Os documentos do provedor dizem para usar only when you want to expose an API for application-wide configuration that must be made before the application starts. This is usually interesting only for reusable services whose behavior might need to vary slightly between applications, então não parece possível, certo?
Qix 9/15
191
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 injeção de dependência .
cO valor armazenado é obtido primeiro pela obtenção de uma instância newing fne, em seguida, pela execução de um $getmétodo da instância.
O que significa que há algo como um objeto de cache dentro do AngularJS, cujo valor de cada injeção é atribuído apenas uma vez, quando foram injetados pela primeira vez e onde:
Eu também gosto mais desta resposta. O objetivo de todos eles é fornecer acesso a um objeto sempre que necessário através do DI. Normalmente você está bem com factorys. Os únicos motivos pelos quais serviceexistem são linguagens como CoffeeScript, TypeScript, ES6 etc., para que você possa usar a sintaxe da classe. Você precisa providerapenas se seu módulo for usado em vários aplicativos com configurações diferentes usando app.config(). Se o seu serviço for um singleton puro ou for capaz de criar instâncias de algo, isso depende apenas da sua implementação.
Andreas Linnert
137
Serviço x fornecedor x fábrica:
Estou tentando simplificar. É tudo sobre o conceito básico de JavaScript.
Primeiro de tudo, vamos falar sobre serviços no AngularJS!
O que é serviço:
no AngularJS, serviçonada mais é que um objeto JavaScript singleton que pode armazenar alguns métodos ou propriedades úteis. Esse objeto singleton é criado por ngApp (aplicativo Angular) e é compartilhado entre todos os controladores no aplicativo atual. Quando o Angularjs instancia um objeto de serviço, ele registra esse objeto de serviço com um nome de serviço exclusivo. Portanto, sempre que precisamos de uma instância de serviço, o Angular pesquisa no registro esse nome de serviço e retorna a referência ao objeto de serviço. Para que possamos chamar método, acessar propriedades etc. no objeto de serviço. Você pode ter dúvidas se também pode colocar propriedades, métodos no escopo objeto dos controladores! Então, por que você precisa de objeto de serviço? As respostas são: os serviços são compartilhados entre vários escopos de controladores. Se você colocar algumas propriedades / métodos no objeto de escopo de um controlador, ele estará disponível apenas no escopo atual.
Portanto, se houver três escopos de controlador, sejam controllerA, controllerB e controllerC, todos compartilharão a mesma instância de serviço.
O AngularJS fornece métodos diferentes para registrar um serviço. Aqui vamos nos concentrar em três métodos: fábrica (..), serviço (..), provedor (..);
O AngularJS fornece o método 'factory (' serviceName ', fnFactory)' que utiliza dois parâmetros, serviceName e uma função JavaScript. Angular cria instância de serviço chamando a função fnFactory () como abaixo.
var serviceInstace = fnFactory();
A função passada pode definir um objeto e retornar esse objeto. O AngularJS simplesmente armazena essa referência de objeto em uma variável que é passada como primeiro argumento. Tudo o que for retornado do fnFactory será vinculado ao serviceInstance. Em vez de retornar o objeto, também podemos retornar funções, valores, etc. O que retornarmos estará disponível para a instância de serviço.
Exemplo:
var app= angular.module('myApp',[]);//creating service using factory method
app.factory('factoryPattern',function(){var data={'firstName':'Tom','lastName':' Cruise',
greet:function(){
console.log('hello!'+this.firstName +this.lastName);}};//Now all the properties and methods of data object will be available in our service objectreturn data;});
Por outro lado, podemos registrar um serviço. A única diferença é a maneira como o AngularJS tenta instanciar o objeto de serviço. Desta vez, o angular usa a palavra-chave 'new' e chama a função construtora como algo abaixo.
var serviceInstance =new fnServiceConstructor();
Na função construtora, podemos usar a palavra-chave 'this' para adicionar propriedades / métodos ao objeto de serviço. exemplo:
//Creating a service using the service methodvar app= angular.module('myApp',[]);
app.service('servicePattern',function(){this.firstName ='James';this.lastName =' Bond';this.greet =function(){
console.log('My Name is '+this.firstName +this.lastName);};});
Função do provedor:
A função Provider () é a outra maneira de criar serviços. Vamos nos interessar em criar um serviço que apenas exiba alguma mensagem de saudação ao usuário. Mas também queremos fornecer uma funcionalidade para que o usuário possa definir sua própria mensagem de saudação. Em termos técnicos, queremos criar serviços configuráveis. Como podemos fazer isso ? Deve haver uma maneira de que o aplicativo possa transmitir suas mensagens de saudação personalizadas e o Angularjs disponibilizá-lo para a função de fábrica / construtor que cria nossa instância de serviços. Nesse caso, a função provider () faz o trabalho. usando a função provider (), podemos criar serviços configuráveis.
Podemos criar serviços configuráveis usando a sintaxe do provedor, conforme indicado abaixo.
/*step1:define a service */
app.provider('service',function serviceProviderConstructor(){});/*step2:configure the service */
app.config(function configureService(serviceProvider){});
Como a sintaxe do provedor funciona internamente?
O objeto 1.Provider é criado usando a função construtora que definimos em nossa função de provedor.
var serviceProvider =new serviceProviderConstructor();
2.A função que passamos em app.config () é executada. Isso é chamado de fase de configuração, e aqui temos a chance de personalizar nosso serviço.
configureService(serviceProvider);
3. Finalmente, a instância de serviço é criada chamando o método $ get de serviceProvider.
serviceInstance = serviceProvider.$get()
Código de amostra para criar serviço usando sintaxe de fornecimento:
var app= angular.module('myApp',[]);
app.provider('providerPattern',function providerConstructor(){//this function works as constructor function for providerthis.firstName ='Arnold ';this.lastName =' Schwarzenegger';this.greetMessage =' Welcome, This is default Greeting Message';//adding some method which we can call in app.config() functionthis.setGreetMsg =function(msg){if(msg){this.greetMessage = msg ;}};//We can also add a method which can change firstName and lastNamethis.$get =function(){var firstName =this.firstName;var lastName =this.lastName ;var greetMessage =this.greetMessage;var data={
greet:function(){
console.log('hello, '+ firstName + lastName+'! '+ greetMessage);}};return data ;};});
app.config(function(providerPatternProvider){
providerPatternProvider.setGreetMsg(' How do you do ?');});
Fábrica use uma função de fábrica que retorne uma instância de serviço.
serviceInstance = fnFactory ();
O serviço usa uma função construtora e o Angular invoca essa função construtora usando a palavra-chave 'new' para criar a instância do serviço.
serviceInstance = novo fnServiceConstructor ();
O provedor define uma função providerConstructor, essa função providerConstructor define uma função de fábrica $ get . Chamadas angulares $ get () para criar o objeto de serviço. A sintaxe do provedor tem uma vantagem adicional de configurar o objeto de serviço antes que ele seja instanciado.
serviceInstance = $ get ();
Como apontado por várias pessoas aqui corretamente, fábrica, provedor, serviço e até valor e constante são versões da mesma coisa. Você pode dissecar o mais geral providerem todos eles. Igual a:
Você atribui uma função ao AngularJS, o AngularJS chamará new para instancia-lo. É a instância criada pelo AngularJS que será armazenada em cache e injetada quando o serviço for solicitado. Como new foi usado para instanciar o serviço, a palavra - chave é válida e refere-se à instância.
Exemplo:
app.service('service',function(){var name ='';this.setName =function(newName){
name = newName;}this.getName =function(){return name;}});
Você atribui uma função ao AngularJS e o AngularJS chamará sua $getfunção. É o valor de retorno da $getfunção que será armazenado em cache e injetado quando o serviço for solicitado.
Os provedores permitem que você configure o provedor antes que o AngularJS chame o $getmétodo para obter o injetável.
Exemplo:
app.provider('provider',function(){var name ='';this.setName =function(newName){
name = newName;}this.$get =function(){return{
name: name
}}})
Notei algo interessante ao brincar com os provedores.
A visibilidade dos injetáveis é diferente para os fornecedores e para os serviços e fábricas. Se você declarar uma "constante" AngularJS (por exemplo,myApp.constant('a', 'Robert'); ), poderá injetá-la em serviços, fábricas e fornecedores.
Mas se você declarar um "valor" do AngularJS (por exemplo., myApp.value('b', {name: 'Jones'});), Poderá injetá-lo em serviços e fábricas, mas NÃO na função de criação de provedor. No entanto, você pode injetá-lo na $getfunção que você define para o seu provedor. Isso é mencionado na documentação do AngularJS, mas é fácil perder. Você pode encontrá-lo na página% de fornecimento nas seções sobre métodos de valor e constante.
Esta é uma parte muito confusa para o novato e tentei esclarecê-lo com palavras fáceis
Serviço AngularJS: é usado para compartilhar funções de utilitário com a referência de serviço no controlador. O serviço é de natureza única, portanto, para um serviço, apenas uma instância é criada no navegador e a mesma referência é usada em toda a página.
No serviço, criamos nomes de função como propriedade com este objeto.
AngularJS Factory: o objetivo do Factory também é o mesmo do Service, no entanto, neste caso, criamos um novo objeto e adicionamos funções como propriedades desse objeto e, no final, retornamos esse objeto.
Provedor AngularJS: o objetivo disso é novamente o mesmo, no entanto, o Provedor fornece a saída de sua função $ get.
Portanto, para o serviço, o que se torna o componente AngularJS é a instância do objeto da classe que é representada pela função de declaração de serviço. Para a fábrica, é o resultado retornado da função de declaração de fábrica. A fábrica pode se comportar da mesma maneira que o serviço:
var factoryAsService =function(injection){returnnewfunction(injection){// Service content}}
A maneira mais simples de pensar é a seguinte:
Serviço é uma instância de objeto singleton. Use serviços se desejar fornecer um objeto singleton para seu código.
Fábrica é uma classe. Use fábricas se desejar fornecer classes personalizadas para o seu código (não pode ser feito com serviços porque eles já estão instanciados).
O exemplo de 'classe' de fábrica é fornecido nos comentários, bem como a diferença de fornecedor.
como um serviço pode ser um singleton se for instanciado toda vez que for usado? eu posso colocar minha cabeça em torno disso ...
joe
O serviço é instanciado apenas uma vez durante a resolução de dependências e, quando você solicita o serviço do injector, obtém sempre a mesma instância. Pode ser facilmente verificado aqui: jsfiddle.net/l0co/sovtu55t/1 , execute-o com o console. O console mostra que o serviço é instanciado apenas uma vez.
Lukasz Frankowski
Ah eu vejo. eu estava esperando para ser capaz de, literalmente, new MyService()ou algo :)
joe
33
Meu esclarecimento sobre este assunto:
Basicamente, todos os tipos mencionados (serviço, fábrica, provedor etc.) estão apenas criando e configurando variáveis globais (que são obviamente globais para todo o aplicativo), exatamente como eram as variáveis globais antiquadas.
Embora as variáveis globais não sejam recomendadas, o uso real dessas variáveis globais é fornecer injeção de dependência , passando a variável para o controlador relevante.
Existem muitos níveis de complicações na criação dos valores para as "variáveis globais":
Constante
Define uma constante real que não deve ser modificada durante todo o aplicativo, assim como as constantes em outros idiomas (algo que falta no JavaScript).
Valor
Este é um valor ou objeto modificável e serve como alguma variável global, que pode até ser injetada ao criar outros serviços ou fábricas (veja mais adiante). No entanto, ele deve ser um " valor literal ", o que significa que é preciso escrever o valor real e não pode usar nenhuma lógica de computação ou programação (em outras palavras, 39 ou myText ou {prop: "value"} estão OK, mas 2 +2 não é).
Fábrica
Um valor mais geral, que pode ser calculado imediatamente. Ele funciona passando uma função para o AngularJS com a lógica necessária para calcular o valor e o AngularJS o executa e salva o valor de retorno na variável nomeada.
Observe que é possível retornar um objeto (nesse caso, ele funcionará de maneira semelhante a um serviço ) ou uma função (que será salva na variável como uma função de retorno de chamada).
Serviço
Um serviço é uma versão mais simplificada da fábrica que é válida apenas quando o valor é um objeto e permite gravar qualquer lógica diretamente na função (como se fosse um construtor), além de declarar e acessar as propriedades do objeto usando a palavra - chave this .
Provedor
Diferente de um serviço que é uma versão simplificada da fábrica , um provedor é uma maneira mais complexa, porém mais flexível, de inicializar as variáveis "globais", com a maior flexibilidade sendo a opção de definir valores no app.config.
Funciona como usar uma combinação de serviço e provedor , passando para o provedor uma função que possui propriedades declaradas usando a palavra - chave this , que pode ser usada no app.config.
Em seguida, ele precisa ter uma função $ .get separada, que é executada pelo AngularJS após definir as propriedades acima através do app.configarquivo, e essa função $ .get se comporta exatamente como a fábrica acima, em que seu valor de retorno é usado para inicializar as variáveis "globais".
Você não misturou a fábrica e serviço? Serviços cria onde a fábrica retorna.
Flavien Volken
Ao declarar o nome do serviço como um argumento injetável, você receberá uma instância da função. Em outras palavras, novo FunctionYouPassedToService (). Essa instância do objeto se torna o objeto de serviço que o AngularJS registra e injeta posteriormente em outros serviços / controladores, se necessário. // factory Ao declarar factoryname como um argumento injetável, você receberá o valor retornado invocando a referência de função passada para module.factory.
sajan
Ok, então ... em angular da fábrica é um singleton , onde o "serviço" é uma verdade, uma fábrica (em termos comuns design patterns)
Fábrica e serviço são as receitas mais usadas. A única diferença entre eles é que a receita de serviço funciona melhor para objetos de um tipo personalizado, enquanto a fábrica pode produzir primitivas e funções JavaScript.
A receita do provedor é o tipo de receita principal e todas as outras são apenas açúcar sintático.
O provedor é o tipo de receita mais complexo. Você não precisa dele, a menos que esteja criando um pedaço de código reutilizável que precise de configuração global.
Todas as boas respostas já. Gostaria de acrescentar mais alguns pontos sobre Serviço e Fábrica . Junto com a diferença entre serviço / fábrica. E também se pode ter perguntas como:
Devo usar o serviço ou a fábrica? Qual é a diferença?
Eles fazem o mesmo ou têm o mesmo comportamento?
Vamos começar com a diferença entre serviço e fábrica:
Ambos são singletons : sempre que o Angular os encontra como dependência pela primeira vez, ele cria uma única instância de serviço / fábrica. Depois que a instância é criada, a mesma instância é usada para sempre.
Pode ser usado para modelar um objeto com comportamento : ambos podem ter métodos, variáveis de estado interno e assim por diante. Embora a maneira como você escreve esse código seja diferente.
Serviços:
Um serviço é uma função construtora, e o Angular irá instancia-lo chamando new yourServiceName(). Isso significa algumas coisas.
Funções e variáveis de instância serão propriedades de this .
Você não precisa retornar um valor. Quando o Angular chama new yourServiceName(), ele recebe o thisobjeto com todas as propriedades que você coloca nele.
Quando o Angular injeta esse MyServiceserviço em um controlador que depende dele, esse controlador recebe um MyServiceque pode chamar funções, por exemplo, MyService.aServiceMethod ().
Seja cuidadoso com this :
Como o serviço construído é um objeto, os métodos dentro dele podem se referir a isso quando são chamados:
Você pode ficar tentado a entrar ScoreKeeper.setScoreem uma cadeia de promessas, por exemplo, se inicializou a pontuação pegando-a no servidor: $http.get('/score').then(ScoreKeeper.setScore).O problema é que ScoreKeeper.setScoreserá chamado com thisvinculado nulle você obterá erros. A melhor maneira seria $http.get('/score').then(ScoreKeeper.setScore.bind(ScoreKeeper)). Se você optar por usar isso em seus métodos de serviço ou não, tome cuidado com a forma como os chama.
Retornando um valor deService :
Devido à maneira como os construtores JavaScript funcionam, se você retornar um valor complexo (i.e., an Object)de uma constructorfunção, o chamador obterá esse Objeto em vez da instância.
Isso significa que você pode basicamente copiar e colar o exemplo de fábrica abaixo, substituir factorypor servicee ele funcionará:
angular.service('MyService',function($http){var api ={};
api.aServiceMethod=function(){return $http.get('/users');};return api;});
Portanto, quando Angular constrói seu serviço com o novo MyService (), ele obtém esse objeto api em vez da instância do MyService.
Esse é o comportamento para quaisquer valores complexos (objetos, funções), mas não para tipos primitivos.
Fábricas:
Uma fábrica é uma função antiga simples que retorna um valor. O valor de retorno é o que é injetado em coisas que dependem da fábrica. Um padrão de fábrica típico em Angular é retornar um objeto com funções como propriedades, assim:
angular.factory('MyFactory',function($http){var api ={};
api.aFactoryMethod=function(){return $http.get('/users');};return api;});
O valor injetado para uma dependência de fábrica é o valor de retorno da fábrica e não precisa ser um objeto. Poderia ser uma função
Respostas para as perguntas 1 e 2 acima:
Na maioria das vezes, continue usando fábricas para tudo. O comportamento deles é mais fácil de entender. Não há escolha a fazer sobre retornar ou não um valor e, além disso, não há bugs a serem introduzidos se você fizer a coisa errada.
Ainda me refiro a eles como "serviços" quando estou falando de injetá-los como dependências.
O comportamento do serviço / fábrica é muito semelhante e algumas pessoas dizem que qualquer um deles está bem. Isso é verdade, mas acho mais fácil seguir os conselhos do guia de estilo de John Papa e permanecer nas fábricas. **
Já existem boas respostas, mas só quero compartilhar essa.
Primeiro de tudo: o provedor é o caminho / receita para criar umservice (objeto singleton) que deve ser injetado pelo $ injector (como o AngulaJS segue o padrão de IoC).
E Valor, Fábrica, Serviço e Constante (4 vias) - o açúcar sintático sobre a maneira / recebimento do Fornecedor .
Depois de ler todos esses posts, criou mais confusão para mim .. Mas ainda assim tudo é informação valiosa .. finalmente encontrei a tabela a seguir que dará informações com comparação simples
O injetor usa receitas para criar dois tipos de objetos: serviços e objetos de finalidade especial
Existem cinco tipos de receita que definem como criar objetos: Valor, Fábrica, Serviço, Fornecedor e Constante.
Fábrica e serviço são as receitas mais usadas. A única diferença entre eles é que a receita de serviço funciona melhor para objetos de um tipo personalizado, enquanto o Factory pode produzir primitivas e funções JavaScript.
A receita do provedor é o tipo de receita principal e todas as outras são apenas açúcar sintático.
O provedor é o tipo de receita mais complexo. Você não precisa dele, a menos que esteja criando um pedaço de código reutilizável que precise de configuração global.
Todos os objetos de finalidade especial, exceto o Controlador, são definidos nas receitas de fábrica.
E, para iniciantes, entenda: - Isso pode não corrigir o caso de uso, mas em alto nível é o que usamos para esses três.
Se você deseja usar no módulo angular, a função de configuração deve ser criada como provedor
Aqui está um código que eu criei como um modelo de código para a fábrica de objetos no AngularjS. Eu usei um Car / CarFactory como exemplo para ilustrar. Cria um código de implementação simples no controlador.
<script>
angular.module('app',[]).factory('CarFactory',function(){/**
* BroilerPlate Object Instance Factory Definition / Example
*/this.Car=function(){// initialize instance properties
angular.extend(this,{
color :null,
numberOfDoors :null,
hasFancyRadio :null,
hasLeatherSeats :null});// generic setter (with optional default value)this.set=function(key, value, defaultValue, allowUndefined){// by default,if(typeof allowUndefined ==='undefined'){// we don't allow setter to accept "undefined" as a value
allowUndefined =false;}// if we do not allow undefined values, and..if(!allowUndefined){// if an undefined value was passed inif(value ===undefined){// and a default value was specifiedif(defaultValue !==undefined){// use the specified default value
value = defaultValue;}else{// otherwise use the class.prototype.defaults value
value =this.defaults[key];}// end if/else}// end if}// end if// update this[key]= value;// return reference to this object (fluent)returnthis;};// end this.set()};// end this.Car class definition// instance properties default valuesthis.Car.prototype.defaults ={
color:'yellow',
numberOfDoors:2,
hasLeatherSeats:null,
hasFancyRadio:false};// instance factory method / constructorthis.Car.prototype.instance =function(params){returnnewthis.constructor().set('color', params.color).set('numberOfDoors', params.numberOfDoors).set('hasFancyRadio', params.hasFancyRadio).set('hasLeatherSeats', params.hasLeatherSeats);};returnnewthis.Car();})// end Factory Definition.controller('testCtrl',function($scope,CarFactory){
window.testCtrl = $scope;// first car, is red, uses class default for:// numberOfDoors, and hasLeatherSeats
$scope.car1 =CarFactory.instance({
color:'red'});// second car, is blue, has 3 doors, // uses class default for hasLeatherSeats
$scope.car2 =CarFactory.instance({
color:'blue',
numberOfDoors:3});// third car, has 4 doors, uses class default for // color and hasLeatherSeats
$scope.car3 =CarFactory.instance({
numberOfDoors:4});// sets an undefined variable for 'hasFancyRadio',// explicitly defines "true" as default when value is undefined
$scope.hasFancyRadio =undefined;
$scope.car3.set('hasFancyRadio', $scope.hasFancyRadio,true);// fourth car, purple, 4 doors,// uses class default for hasLeatherSeats
$scope.car4 =CarFactory.instance({
color:'purple',
numberOfDoors:4});// and then explicitly sets hasLeatherSeats to undefined
$scope.hasLeatherSeats =undefined;
$scope.car4.set('hasLeatherSeats', $scope.hasLeatherSeats,undefined,true);// in console, type window.testCtrl to see the resulting objects});</script>
Aqui está um exemplo mais simples. Estou usando algumas bibliotecas de terceiros que esperam um objeto "Posição" expondo latitude e longitude, mas através de diferentes propriedades do objeto. Como não queria invadir o código do fornecedor, ajustei os objetos "Posição" que estava passando.
angular.module('app').factory('PositionFactory',function(){/**
* BroilerPlate Object Instance Factory Definition / Example
*/this.Position=function(){// initialize instance properties // (multiple properties to satisfy multiple external interface contracts)
angular.extend(this,{
lat :null,
lon :null,
latitude :null,
longitude :null,
coords:{
latitude:null,
longitude:null}});this.setLatitude =function(latitude){this.latitude = latitude;this.lat = latitude;this.coords.latitude = latitude;returnthis;};this.setLongitude =function(longitude){this.longitude = longitude;this.lon = longitude;this.coords.longitude = longitude;returnthis;};};// end class definition// instance factory method / constructorthis.Position.prototype.instance =function(params){returnnewthis.constructor().setLatitude(params.latitude).setLongitude(params.longitude);};returnnewthis.Position();})// end Factory Definition.controller('testCtrl',function($scope,PositionFactory){
$scope.position1 =PositionFactory.instance({latitude:39, longitude:42.3123});
$scope.position2 =PositionFactory.instance({latitude:39, longitude:42.3333});})// end controller
Usando como referência esta página e a documentação (que parece ter melhorado muito desde a última vez que procurei), montei a seguinte demonstração do mundo real (-ish) que usa quatro dos cinco tipos de provedor; Valor, constante, fábrica e fornecedor completo.
HTML:
<divng-controller="mainCtrl as main"><h1>{{main.title}}*</h1><h2>{{main.strapline}}</h2><p>Earn {{main.earn}} per click</p><p>You've earned {{main.earned}} by clicking!</p><buttonng-click="main.handleClick()">Click me to earn</button><small>* Not actual money</small></div>
aplicativo
var app = angular.module('angularProviders',[]);// A CONSTANT is not going to change
app.constant('range',100);// A VALUE could change, but probably / typically doesn't
app.value('title','Earn money by clicking');
app.value('strapline','Adventures in ng Providers');// A simple FACTORY allows us to compute a value @ runtime.// Furthermore, it can have other dependencies injected into it such// as our range constant.
app.factory('random',function randomFactory(range){// Get a random number within the range defined in our CONSTANTreturnMath.random()* range;});// A PROVIDER, must return a custom type which implements the functionality // provided by our service (see what I did there?).// Here we define the constructor for the custom type the PROVIDER below will // instantiate and return.varMoney=function(locale){// Depending on locale string set during config phase, we'll// use different symbols and positioning for any values we // need to display as currencythis.settings ={
uk:{
front:true,
currency:'£',
thousand:',',decimal:'.'},
eu:{
front:false,
currency:'€',
thousand:'.',decimal:','}};this.locale = locale;};// Return a monetary value with currency symbol and placement, and decimal // and thousand delimiters according to the locale set in the config phase.Money.prototype.convertValue =function(value){var settings =this.settings[this.locale],
decimalIndex, converted;
converted =this.addThousandSeparator(value.toFixed(2), settings.thousand);
decimalIndex = converted.length -3;
converted = converted.substr(0, decimalIndex)+
settings.decimal+
converted.substr(decimalIndex +1);
converted = settings.front ?
settings.currency + converted :
converted + settings.currency;return converted;};// Add supplied thousand separator to supplied valueMoney.prototype.addThousandSeparator =function(value, symbol){returnvalue.toString().replace(/\B(?=(\d{3})+(?!\d))/g, symbol);};// PROVIDER is the core recipe type - VALUE, CONSTANT, SERVICE & FACTORY// are all effectively syntactic sugar built on top of the PROVIDER construct// One of the advantages of the PROVIDER is that we can configure it before the// application starts (see config below).
app.provider('money',functionMoneyProvider(){var locale;// Function called by the config to set up the providerthis.setLocale =function(value){
locale =value;};// All providers need to implement a $get method which returns// an instance of the custom class which constitutes the servicethis.$get =function moneyFactory(){returnnewMoney(locale);};});// We can configure a PROVIDER on application initialisation.
app.config(['moneyProvider',function(moneyProvider){
moneyProvider.setLocale('uk');//moneyProvider.setLocale('eu'); }]);// The ubiquitous controller
app.controller('mainCtrl',function($scope, title, strapline, random, money){// Plain old VALUE(s)this.title = title;this.strapline = strapline;this.count =0;// Compute values using our money provider this.earn = money.convertValue(random);// random is computed @ runtimethis.earned = money.convertValue(0);this.handleClick =function(){this.count ++;this.earned = money.convertValue(random *this.count);};});
como Factory, Service e Constant - são apenas açúcar sintático em cima de uma receita de provedor?
OU
como fábrica, serviço e fornecedores são semelhantes internamente
basicamente o que acontece é
Quando você factory()cria um conjunto de configurações functionfornecido no segundo argumento para o provedor $gete o retorna ( provider(name, {$get:factoryFn })), tudo o que você obtém é que providernão há nenhuma propriedade / método além$get disso provider(significa que você não pode configurar isso)
Ao fazer um service()retorno, você fornece a uma fábrica () um functionque injeta constructor(retorna a instância do construtor que você forneceu em seu serviço) e o devolve
Código fonte de serviço
function service(name,constructor){return factory(name,['$injector',function($injector){return $injector.instantiate(constructor);}]);};
Então, basicamente, em ambos os casos, você eventualmente obtém um conjunto de provedores $ definido para sua função que você forneceu, mas você pode fornecer algo a mais que $ get, como você pode fornecer originalmente no provedor () para o bloco de configuração
Conheço muitas respostas excelentes, mas tenho que compartilhar minha experiência de usar
1. servicena maioria dos casos de padrão
2. factoryusado para criar o serviço nessa instância específica
Um pouco tarde para a festa. Mas achei que isso seria mais útil para quem gostaria de aprender (ou ter clareza) sobre o desenvolvimento de serviços personalizados JS angulares usando metodologias de fábrica, serviço e provedor.
Encontrei este vídeo que explica claramente sobre as metodologias de fábrica, serviço e provedor para o desenvolvimento de serviços personalizados do AngularJS:
O código postado aqui é copiado diretamente da fonte acima, para beneficiar os leitores.
O código para o serviço personalizado baseado em "fábrica" é o seguinte (que acompanha as versões de sincronização e assíncrona, além de chamar o serviço http):
O código para a metodologia "service" para serviços personalizados (isso é bastante semelhante ao 'factory', mas diferente do ponto de vista da sintaxe):
Finalmente, a interface do usuário que funciona com qualquer um dos serviços acima:
<html><head><title></title><scriptsrc="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script><scripttype="text/javascript"src="t03.js"></script></head><bodyng-app="app"><divng-controller="emp"><div>
Value of a is {{a}},
but you can change
<inputtype=textng-model="a"/><br>
Value of b is {{b}},
but you can change
<inputtype=textng-model="b"/><br></div>
Sum = {{sum}}<br><buttonng-click="doSum()">Calculate</button></div></body></html>
Apenas para esclarecer as coisas, na fonte AngularJS, você pode ver um serviço que apenas chama a função de fábrica que, por sua vez, chama a função de provedor:
function factory(name, factoryFn){return provider(name,{ $get: factoryFn });}function service(name,constructor){return factory(name,['$injector',function($injector){return $injector.instantiate(constructor);}]);}
Vamos discutir as três maneiras de lidar com a lógica de negócios no AngularJS de uma maneira simples: ( Inspirado no curso Coursera AngularJS do Yaakov )
SERVIÇO :
Sintaxe:
app.js
var app = angular.module('ServiceExample',[]);var serviceExampleController =
app.controller('ServiceExampleController',ServiceExampleController);var serviceExample = app.service('NameOfTheService',NameOfTheService);ServiceExampleController.$inject =['NameOfTheService']//protects from minification of js filesfunctionServiceExampleController(NameOfTheService){
serviceExampleController =this;
serviceExampleController.data =NameOfTheService.getSomeData();}functionNameOfTheService(){
nameOfTheService =this;
nameOfTheService.data ="Some Data";
nameOfTheService.getSomeData =function(){return nameOfTheService.data;}}
index.html
<divng-controller="ServiceExampleController as serviceExample">
{{serviceExample.data}}
</div>
Recursos do serviço:
Instanciado preguiçosamente : se não for injetado, nunca será instanciado. Portanto, para usá-lo, será necessário injetá-lo em um módulo.
Singleton : se injetado em vários módulos, todos terão acesso a apenas uma instância específica. É por isso que é muito conveniente compartilhar dados entre diferentes controladores.
FÁBRICA
Primeiro, vamos dar uma olhada na sintaxe:
app.js :
var app = angular.module('FactoryExample',[]);var factoryController = app.controller('FactoryController',FactoryController);var factoryExampleOne = app.factory('NameOfTheFactoryOne',NameOfTheFactoryOne);var factoryExampleTwo = app.factory('NameOfTheFactoryTwo',NameOfTheFactoryTwo);//first implementation where it returns a functionfunctionNameOfTheFactoryOne(){var factory =function(){returnnewSomeService();}return factory;}//second implementation where an object literal would be returnedfunctionNameOfTheFactoryTwo(){var factory ={
getSomeService :function(){returnnewSomeService();}};return factory;}
Agora, usando os dois acima no controlador:
var factoryOne =NameOfTheFactoryOne()//since it returns a function
factoryOne.someMethod();var factoryTwo =NameOfTheFactoryTwo.getSomeService();//accessing the object
factoryTwo.someMethod();
Características da fábrica:
Segue o padrão de design da fábrica. A fábrica é um local central que produz novos objetos ou funções.
Não apenas produz serviços únicos, mas personalizáveis.
O .service()método é uma fábrica que sempre produz o mesmo tipo de serviço, que é um singleton e sem nenhuma 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.
FORNECEDOR
Vamos novamente dar uma olhada na sintaxe primeiro:
O provedor é o método mais flexível de criar serviços no Angular.
Não apenas podemos criar uma fábrica configurável dinamicamente, mas no momento de usá-la, com o método do provedor, poderíamos configurar a fábrica de forma personalizada apenas uma vez no bootstrap de todo o aplicativo.
A fábrica pode ser usada em todo o aplicativo com configurações personalizadas. Em outras palavras, podemos configurar esta fábrica antes que o aplicativo seja iniciado. De fato, na documentação angular, é mencionado que o método do provedor é o que realmente é executado nos bastidores quando configuramos nossos serviços com um .serviceou outro .factorymétodo.
A $geté uma função diretamente anexada à instância do provedor. Essa função é uma função de fábrica . Em outras palavras, é exatamente como o que usamos para fornecer ao .factorymétodo. Nessa função, criamos nosso próprio serviço. Essa $getpropriedade, que é uma função, é o que torna o provedor um provedor . O AngularJS espera que o provedor tenha uma propriedade $ get cujo valor é uma função que o Angular tratará como uma função de fábrica. Mas o que torna toda essa configuração de provedor muito especial é o fato de podermos fornecer algum configobjeto dentro do provedor de serviços, e isso geralmente vem com padrões que podemos substituir posteriormente na etapa, onde podemos configurar o aplicativo inteiro.
Fábrica: a fábrica em que você realmente cria um objeto dentro da fábrica e o devolve. service: o serviço, você apenas possui uma função padrão que usa a palavra-chave this para definir a função. provider: O provedor tem um $ get you define e pode ser usado para obter o objeto que retorna os dados.
Essencialmente, Provedor, Fábrica e Serviço são todos Serviços. Um Factory é um caso especial de um Serviço quando tudo o que você precisa é de uma função $ get (), permitindo escrever com menos código.
As principais diferenças entre serviços, fábricas e fornecedores são suas complexidades. Os serviços são a forma mais simples, as fábricas são um pouco mais robustas e os provedores são configuráveis em tempo de execução.
Aqui está um resumo de quando usar cada um:
Fábrica : o valor que você está fornecendo precisa ser calculado com base em outros dados.
Serviço : você está retornando um objeto com métodos.
Fornecedor : você deseja configurar, durante a fase de configuração, o objeto que será criado antes de ser criado. Use o provedor principalmente na configuração do aplicativo, antes que o aplicativo seja totalmente inicializado.
erm. Valor, Fábrica, Serviço e Constante - são apenas açúcar sintático em cima de uma receita de fornecedor. Angularjs docs - provider
Sudarshan_SMD
Sim, eu concordo, agora com angular 4 não temos essa dor de cabeça mais
eGhoul
4
1. Serviços são objetos únicos que são criados quando necessário e nunca são limpos até o final do ciclo de vida do aplicativo (quando o navegador é fechado). Os controladores são destruídos e limpos quando não são mais necessários.
2. A maneira mais fácil de criar um serviço é usando o método factory (). O método factory () nos permite definir um serviço retornando um objeto que contém funções de serviço e dados de serviço. A função de definição de serviço é onde colocamos nossos serviços injetáveis, como $ http e $ q. Ex:
O método service (), por outro lado, permite criar um serviço definindo uma função construtora. Podemos usar um objeto prototípico para definir nosso serviço, em vez de um objeto javascript bruto. Semelhante ao método factory (), também definiremos os injetáveis na definição da função.
A maneira de nível mais baixo para criar um serviço é usando o método allow (). Essa é a única maneira de criar um serviço que podemos configurar usando a função .config (). Diferentemente dos métodos anteriores, definiremos os injetáveis em uma definição de função definida como. $ Get ().
Açúcar sintático é a diferença . Somente o provedor é necessário. Ou, em outras palavras, apenas o provedor é o angular real, todos os outros são derivados (para reduzir o código). Também existe uma versão simples, chamada Value (), que retorna apenas o valor, sem cálculo ou função. Even Value é derivado do provedor!
Então, por que essas complicações, por que não podemos simplesmente usar o provedor e esquecer todo o resto? Ele deve nos ajudar a escrever código facilmente e nos comunicar melhor. E a resposta direta seria, quanto mais complexo for, melhor será a venda de uma estrutura.
Um provedor que pode retornar value = Value
Um provedor que pode apenas instanciar e retornar = Factory (+ Value)
Um provedor que pode instanciar + fazer algo = Serviço (+ Fábrica, + Valor)
Um provedor = deve conter uma propriedade chamada $ get (+ Factory, + Service, + Value)
A injeção angular nos dá a primeira dica para chegar a essa conclusão.
"$ injector é usado para recuperar instâncias de objetos, conforme definido pelo provedor " não pelo serviço, não pela fábrica, mas pelo provedor.
E uma resposta melhor seria a seguinte: "Um serviço Angular é criado por uma fábrica de serviços. Essas fábricas de serviços são funções que, por sua vez, são criadas por um provedor de serviços. Os provedores de serviços são funções construtoras. Quando instanciadas, elas devem conter uma propriedade. chamado $ get, que mantém a função da fábrica de serviços ".
Então, o provedor principal e o injetor e tudo se encaixará :). E fica interessante no Typescript quando $ get pode ser implementado em um provedor, herdando do IServiceProvider.
service.factory
. Não queria complicar ainda mais esse assunto.services
,factories
eproviders
obras.Respostas:
Na lista de discussão do AngularJS, recebi uma discussão incrível que explica serviço x fábrica x provedor e seu uso de injeção. Compilando as respostas:
Serviços
Sintaxe:
module.service( 'serviceName', function );
Resultado: Ao declarar serviceName como um argumento injetável, você receberá uma instância da função. Em outras palavras
new FunctionYouPassedToService()
.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 .
Fornecedores
Sintaxe:
module.provider( 'providerName', function );
Resultado: Ao declarar providerName como um argumento injetável, você será fornecido
(new ProviderFunction()).$get()
. A função construtora é instanciada antes que o método $ get seja chamado -ProviderFunction
é a referência da função passada para module.provider.Os fornecedores têm a vantagem de poderem ser configurados durante a fase de configuração do módulo.
Veja aqui o código fornecido.
Aqui está uma grande explicação adicional de Misko:
Nesse caso, o injetor simplesmente retorna o valor como está. Mas e se você quiser calcular o valor? Então use uma fábrica
Assim
factory
é uma função que é responsável por criar o valor. Observe que a função de fábrica pode solicitar outras dependências.Mas e se você quiser ter mais OO e ter uma classe chamada Greeter?
Então, para instanciar, você teria que escrever
Então poderíamos pedir 'greeter' em um controlador como este
Mas isso é muito prolixo. Uma maneira mais curta de escrever isso seria
provider.service('greeter', Greeter);
Mas e se quiséssemos configurar a
Greeter
classe antes da injeção? Então poderíamos escreverEntão podemos fazer isso:
Como uma nota lateral,
service
,factory
, evalue
são todos derivados do provedor.fonte
toEqual
egreeter.Greet
é. Por que não usar algo um pouco mais real e relacionável?JS Fiddle Demo
Exemplo "Olá, mundo", com
factory
/service
/provider
:fonte
this
muda o contexto na$get
função? - você não se refere mais ao provedor instanciado nessa função.this
não muda o contexto, na verdade, porque o que está sendo chamado énew Provider()
. $ Get (), para ondeProvider
a função está sendo passadaapp.provider
. Ou seja,$get()
está sendo chamado como método no construídoProvider
, portanto,this
será referidoProvider
como o exemplo sugere.Unknown provider: helloWorldProvider <- helloWorld
ao executar isso localmente? Comentando, o mesmo erro para os outros 2 exemplos. Existe alguma configuração de provedor oculto? (Angular 1.0.8) - Encontrado: stackoverflow.com/questions/12339272/…TL; DR
1) Ao usar um Factory, você cria um objeto, adiciona propriedades a ele e retorna o mesmo objeto. Quando você passar esta fábrica para o seu controlador, essas propriedades no objeto estarão agora disponíveis nesse controlador através da sua fábrica.
2) Ao usar o Serviço , o AngularJS o instancia nos bastidores com a palavra-chave 'new'. Por isso, você adicionará propriedades a 'this' e o serviço retornará 'this'. Quando você passa o serviço para o seu controlador, essas propriedades agora estarão disponíveis nesse controlador através do seu serviço.
3) Os provedores são o único serviço que você pode transmitir para a função .config (). Use um provedor quando desejar fornecer configuração em todo o módulo para seu objeto de serviço antes de disponibilizá-lo.
Não TL; DR
1)
Fábricas de fábrica são a maneira mais popular de criar e configurar um serviço. Realmente não há muito mais do que o TL; DR disse. Você acabou de criar um objeto, adicionar propriedades a ele e retornar o mesmo objeto. Então, quando você passar a fábrica para o seu controlador, essas propriedades no objeto estarão agora disponíveis nesse controlador através da sua fábrica. Um exemplo mais extenso está abaixo.
Agora, quaisquer propriedades que anexarmos a 'service' estarão disponíveis quando passarmos 'myFactory' para o nosso controlador.
Agora vamos adicionar algumas variáveis 'privadas' à nossa função de retorno de chamada. Eles não estarão diretamente acessíveis no controlador, mas, eventualmente, configuraremos alguns métodos getter / setter no 'service' para poder alterar essas variáveis 'privadas' quando necessário.
Aqui você notará que não estamos anexando essas variáveis / funções ao 'serviço'. Estamos simplesmente criando-os para usá-los ou modificá-los posteriormente.
Agora que nossas variáveis e funções auxiliares / particulares estão em vigor, vamos adicionar algumas propriedades ao objeto 'service'. Tudo o que colocamos em 'serviço' pode ser usado diretamente dentro de qualquer controlador no qual passamos 'myFactory'.
Vamos criar métodos setArtist e getArtist que simplesmente retornam ou definem o artista. Também vamos criar um método que chamará a API do iTunes com nosso URL criado. Esse método retornará uma promessa que será cumprida assim que os dados voltarem da API do iTunes. Se você não teve muita experiência no uso de promessas no AngularJS, recomendo fazer um mergulho profundo nelas.
Abaixo, o setArtist aceita um artista e permite que você o defina. O getArtist retorna o artista. O callItunes chama primeiro makeUrl () para criar o URL que usaremos com nossa solicitação $ http. Em seguida, ele configura um objeto de promessa, faz uma solicitação $ http com nosso URL final e, como $ http retorna uma promessa, podemos chamar .success ou .error após nossa solicitação. Em seguida, resolvemos nossa promessa com os dados do iTunes ou a rejeitamos com uma mensagem dizendo 'Houve um erro'.
Agora nossa fábrica está completa. Agora podemos injetar 'myFactory' em qualquer controlador e, em seguida, poderemos chamar nossos métodos que anexamos ao nosso objeto de serviço (setArtist, getArtist e callItunes).
No controlador acima, estamos injetando no serviço 'myFactory'. Em seguida, definimos propriedades em nosso objeto $ scope com dados de 'myFactory'. O único código complicado acima é se você nunca lidou com promessas antes. Como o callItunes está retornando uma promessa, podemos usar o método .then () e definir apenas $ scope.data.artistData quando nossa promessa for cumprida com os dados do iTunes. Você notará que nosso controlador é muito 'fino' (esta é uma boa prática de codificação). Todos os nossos dados lógicos e persistentes estão localizados em nosso serviço, não em nosso controlador.
2) Serviço
Talvez a maior coisa a saber quando se lida com a criação de um Serviço é que ele é instanciado com a palavra-chave 'new'. Para os gurus do JavaScript, isso deve fornecer uma grande dica sobre a natureza do código. Para aqueles com conhecimentos limitados em JavaScript ou para aqueles que não conhecem muito bem o que a palavra-chave 'new' realmente faz, vamos revisar alguns fundamentos do JavaScript que eventualmente nos ajudarão a entender a natureza de um Serviço.
Para realmente ver as alterações que ocorrem quando você invoca uma função com a palavra-chave 'new', vamos criar uma função e invocá-la com a palavra-chave 'new', depois vamos mostrar o que o intérprete faz quando vê a palavra-chave 'new'. Os resultados finais serão os mesmos.
Primeiro, vamos criar nosso Construtor.
Essa é uma função típica do construtor JavaScript. Agora, sempre que invocarmos a função Pessoa usando a palavra-chave 'new', 'this' será vinculado ao objeto recém-criado.
Agora, vamos adicionar um método ao protótipo de nossa Person, para que fique disponível em todas as instâncias da nossa classe de Person.
Agora, como colocamos a função sayName no protótipo, todas as instâncias de Person poderão chamar a função sayName para alertar o nome dessa instância.
Agora que temos nossa função construtora Person e nossa função sayName em seu protótipo, vamos criar uma instância de Person e chamar a função sayName.
Portanto, todo o código para criar um construtor Person, adicionar uma função a seu protótipo, criar uma instância Person e chamar a função em seu protótipo se parece com isso.
Agora, vamos ver o que realmente está acontecendo quando você usa a palavra-chave 'new' em JavaScript. A primeira coisa que você deve notar é que, depois de usar 'new' em nosso exemplo, podemos chamar um método (sayName) em 'tyler' como se fosse um objeto - é porque é. Então, primeiro, sabemos que nosso construtor Person está retornando um objeto, se podemos ver isso no código ou não. Segundo, sabemos que, como nossa função sayName está localizada no protótipo e não diretamente na instância Person, o objeto que a função Person está retornando deve delegar ao seu protótipo em pesquisas com falha. Em termos mais simples, quando chamamos tyler.sayName (), o intérprete diz: “OK, vou olhar para o objeto 'tyler' que acabamos de criar, localize a função sayName e chame-a. Espere um minuto, não o vejo aqui - tudo o que vejo é nome e idade, deixe-me verificar o protótipo. Sim, parece que está no protótipo, deixe-me chamá-lo. ”.
Abaixo está o código de como você pode pensar sobre o que a palavra-chave 'nova' está realmente fazendo em JavaScript. É basicamente um exemplo de código do parágrafo acima. Coloquei a 'visão do intérprete' ou a maneira como o intérprete vê o código dentro das notas.
Agora, tendo esse conhecimento do que a palavra-chave 'new' realmente faz em JavaScript, a criação de um Serviço no AngularJS deve ser mais fácil de entender.
A principal coisa a entender ao criar um Serviço é saber que os Serviços são instanciados com a palavra-chave 'new'. Combinando esse conhecimento com nossos exemplos acima, você deve reconhecer agora que anexará suas propriedades e métodos diretamente a 'this', que serão devolvidos pelo próprio Serviço. Vamos dar uma olhada nisso em ação.
Diferentemente do que fizemos originalmente com o exemplo do Factory, não precisamos criar um objeto e, em seguida, retorná-lo, porque, como mencionado muitas vezes antes, usamos a palavra-chave 'new' para que o intérprete crie esse objeto, faça-o delegar para é protótipo e, em seguida, devolva-o para nós sem que tenhamos que fazer o trabalho.
Primeiramente, vamos criar nossa função 'privada' e auxiliar. Isso deve parecer muito familiar, já que fizemos exatamente a mesma coisa com nossa fábrica. Não vou explicar o que cada linha faz aqui, porque fiz isso no exemplo de fábrica; se você estiver confuso, releia o exemplo de fábrica.
Agora, anexaremos todos os nossos métodos que estarão disponíveis em nosso controlador a 'this'.
Agora, assim como em nossa fábrica, setArtist, getArtist e callItunes estarão disponíveis em qualquer controlador em que passarmos o myService. Aqui está o controlador myService (que é quase exatamente o mesmo que o nosso controlador de fábrica).
Como mencionei antes, quando você realmente entende o que 'novo' faz, os Serviços são quase idênticos às fábricas no AngularJS.
3) Fornecedor
A principal coisa a lembrar sobre os Provedores é que eles são o único serviço que você pode passar para a parte app.config do seu aplicativo. Isso é de grande importância se você precisar alterar parte do objeto de serviço antes que ele esteja disponível em qualquer outro lugar do aplicativo. Embora muito parecido com Serviços / Fábricas, existem algumas diferenças que discutiremos.
Primeiro, configuramos nosso provedor de maneira semelhante ao nosso serviço e fábrica. As variáveis abaixo são nossa função 'privada' e auxiliar.
* Novamente, se qualquer parte do código acima estiver confusa, consulte a seção Factory, onde explico o que isso faz com mais detalhes.
Você pode pensar em Provedores como tendo três seções. A primeira seção são as variáveis / funções 'particulares' que serão modificadas / definidas posteriormente (mostradas acima). A segunda seção são as variáveis / funções que estarão disponíveis na função app.config e, portanto, estão disponíveis para alteração antes de estarem disponíveis em qualquer outro lugar (também mostrado acima). É importante observar que essas variáveis precisam ser anexadas à palavra-chave 'this'. No nosso exemplo, apenas 'thingFromConfig' estará disponível para alteração no app.config. A terceira seção (mostrada abaixo) são todas as variáveis / funções que estarão disponíveis no seu controlador quando você passar o serviço 'myProvider' para esse controlador específico.
Ao criar um serviço com o Provedor, as únicas propriedades / métodos que estarão disponíveis no seu controlador são as propriedades / métodos retornados da função $ get (). O código abaixo coloca $ get on 'this' (que sabemos que eventualmente serão retornados dessa função). Agora, essa função $ get retorna todos os métodos / propriedades que queremos que estejam disponíveis no controlador. Aqui está um exemplo de código.
Agora, o código completo do provedor se parece com isso
Agora, assim como em nossa fábrica e Serviço, setArtist, getArtist e callItunes estarão disponíveis em qualquer controlador em que passarmos o myProvider. Aqui está o controlador myProvider (que é quase exatamente o mesmo que o nosso controlador de fábrica / serviço).
Como mencionado anteriormente, o objetivo principal de criar um serviço com o Provedor é poder alterar algumas variáveis por meio da função app.config antes que o objeto final seja passado para o restante do aplicativo. Vamos ver um exemplo disso.
Agora você pode ver como 'thingFromConfig' é uma string vazia no nosso provedor, mas quando isso aparecer no DOM, será 'Esta frase foi configurada ...'.
fonte
Todos os serviços são singletons ; eles são instanciados uma vez por aplicativo. Eles podem ser de qualquer tipo , seja um primitivo, literal de objeto, função ou até uma instância de um tipo personalizado.
O
value
,factory
,service
,constant
, eprovider
métodos são todos os provedores. Eles ensinam ao Injetor como instanciar os Serviços.decorator
.fonte
Compreendendo o AngularJS Factory, Service and Provider
Tudo isso é usado para compartilhar objetos singleton reutilizáveis. Ajuda a compartilhar código reutilizável em seu aplicativo / vários componentes / módulos.
Fábrica
Uma fábrica é uma função na qual você pode manipular / adicionar lógica antes de criar um objeto, para que o objeto recém-criado seja retornado.
Uso
Pode ser apenas uma coleção de funções como uma classe. Portanto, ele pode ser instanciado em diferentes controladores quando você o injeta nas funções de controlador / fábrica / diretiva. É instanciado apenas uma vez por aplicativo.
Serviço
Simplesmente enquanto olha para os serviços, pense no protótipo da matriz. Um serviço é uma função que instancia um novo objeto usando a palavra-chave 'new'. Você pode adicionar propriedades e funções a um objeto de serviço usando a
this
palavra - chave Ao contrário de uma fábrica, ele não retorna nada (retorna um objeto que contém métodos / propriedades).Uso
Use-o quando precisar compartilhar um único objeto em todo o aplicativo. Por exemplo, detalhes do usuário autenticado, métodos / dados compartilhados, funções do utilitário etc.
Fornecedor
Um provedor é usado para criar um objeto de serviço configurável. Você pode definir a configuração de serviço na função de configuração. Retorna um valor usando a
$get()
função A$get
função é executada na fase de execução em angular.Uso
Quando você precisar fornecer configuração em módulo para o seu objeto de serviço antes de disponibilizá-lo, por exemplo. suponha que você queira definir o URL da API com base no seu ambiente
dev
, como ,stage
ouprod
Espero que isso tenha esclarecido sua compreensão sobre a fábrica, o serviço e o fornecedor .
fonte
only when you want to expose an API for application-wide configuration that must be made before the application starts. This is usually interesting only for reusable services whose behavior might need to vary slightly between applications
, então não parece possível, certo?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 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
.b
O valor armazenado vem denew
ingfn
.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ância.O que significa que há algo como um objeto de cache dentro do AngularJS, 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.fonte
factory
s. Os únicos motivos pelos quaisservice
existem são linguagens como CoffeeScript, TypeScript, ES6 etc., para que você possa usar a sintaxe da classe. Você precisaprovider
apenas se seu módulo for usado em vários aplicativos com configurações diferentes usandoapp.config()
. Se o seu serviço for um singleton puro ou for capaz de criar instâncias de algo, isso depende apenas da sua implementação.Serviço x fornecedor x fábrica:
Estou tentando simplificar. É tudo sobre o conceito básico de JavaScript.
Primeiro de tudo, vamos falar sobre serviços no AngularJS!
O que é serviço: no AngularJS, serviçonada mais é que um objeto JavaScript singleton que pode armazenar alguns métodos ou propriedades úteis. Esse objeto singleton é criado por ngApp (aplicativo Angular) e é compartilhado entre todos os controladores no aplicativo atual. Quando o Angularjs instancia um objeto de serviço, ele registra esse objeto de serviço com um nome de serviço exclusivo. Portanto, sempre que precisamos de uma instância de serviço, o Angular pesquisa no registro esse nome de serviço e retorna a referência ao objeto de serviço. Para que possamos chamar método, acessar propriedades etc. no objeto de serviço. Você pode ter dúvidas se também pode colocar propriedades, métodos no escopo objeto dos controladores! Então, por que você precisa de objeto de serviço? As respostas são: os serviços são compartilhados entre vários escopos de controladores. Se você colocar algumas propriedades / métodos no objeto de escopo de um controlador, ele estará disponível apenas no escopo atual.
Portanto, se houver três escopos de controlador, sejam controllerA, controllerB e controllerC, todos compartilharão a mesma instância de serviço.
Como criar um serviço?
O AngularJS fornece métodos diferentes para registrar um serviço. Aqui vamos nos concentrar em três métodos: fábrica (..), serviço (..), provedor (..);
Use este link para referência de código
Função de fábrica:
Podemos definir uma função de fábrica como abaixo.
O AngularJS fornece o método 'factory (' serviceName ', fnFactory)' que utiliza dois parâmetros, serviceName e uma função JavaScript. Angular cria instância de serviço chamando a função fnFactory () como abaixo.
A função passada pode definir um objeto e retornar esse objeto. O AngularJS simplesmente armazena essa referência de objeto em uma variável que é passada como primeiro argumento. Tudo o que for retornado do fnFactory será vinculado ao serviceInstance. Em vez de retornar o objeto, também podemos retornar funções, valores, etc. O que retornarmos estará disponível para a instância de serviço.
Exemplo:
Função de serviço:
Por outro lado, podemos registrar um serviço. A única diferença é a maneira como o AngularJS tenta instanciar o objeto de serviço. Desta vez, o angular usa a palavra-chave 'new' e chama a função construtora como algo abaixo.
Na função construtora, podemos usar a palavra-chave 'this' para adicionar propriedades / métodos ao objeto de serviço. exemplo:
Função do provedor:
A função Provider () é a outra maneira de criar serviços. Vamos nos interessar em criar um serviço que apenas exiba alguma mensagem de saudação ao usuário. Mas também queremos fornecer uma funcionalidade para que o usuário possa definir sua própria mensagem de saudação. Em termos técnicos, queremos criar serviços configuráveis. Como podemos fazer isso ? Deve haver uma maneira de que o aplicativo possa transmitir suas mensagens de saudação personalizadas e o Angularjs disponibilizá-lo para a função de fábrica / construtor que cria nossa instância de serviços. Nesse caso, a função provider () faz o trabalho. usando a função provider (), podemos criar serviços configuráveis.
Podemos criar serviços configuráveis usando a sintaxe do provedor, conforme indicado abaixo.
Como a sintaxe do provedor funciona internamente?
O objeto 1.Provider é criado usando a função construtora que definimos em nossa função de provedor.
2.A função que passamos em app.config () é executada. Isso é chamado de fase de configuração, e aqui temos a chance de personalizar nosso serviço.
3. Finalmente, a instância de serviço é criada chamando o método $ get de serviceProvider.
Código de amostra para criar serviço usando sintaxe de fornecimento:
Demonstração de trabalho
Resumo:
Fábrica use uma função de fábrica que retorne uma instância de serviço. serviceInstance = fnFactory ();
O serviço usa uma função construtora e o Angular invoca essa função construtora usando a palavra-chave 'new' para criar a instância do serviço. serviceInstance = novo fnServiceConstructor ();
O provedor define uma função providerConstructor, essa função providerConstructor define uma função de fábrica $ get . Chamadas angulares $ get () para criar o objeto de serviço. A sintaxe do provedor tem uma vantagem adicional de configurar o objeto de serviço antes que ele seja instanciado. serviceInstance = $ get ();
fonte
Como apontado por várias pessoas aqui corretamente, fábrica, provedor, serviço e até valor e constante são versões da mesma coisa. Você pode dissecar o mais geral
provider
em todos eles. Igual a:Aqui está o artigo desta imagem:
http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
fonte
Fábrica
Você atribui uma função ao AngularJS, o AngularJS armazenará em cache e injetará o valor de retorno quando a fábrica for solicitada.
Exemplo:
Uso:
Serviço
Você atribui uma função ao AngularJS, o AngularJS chamará new para instancia-lo. É a instância criada pelo AngularJS que será armazenada em cache e injetada quando o serviço for solicitado. Como new foi usado para instanciar o serviço, a palavra - chave é válida e refere-se à instância.
Exemplo:
Uso:
Fornecedor
Você atribui uma função ao AngularJS e o AngularJS chamará sua
$get
função. É o valor de retorno da$get
função que será armazenado em cache e injetado quando o serviço for solicitado.Os provedores permitem que você configure o provedor antes que o AngularJS chame o
$get
método para obter o injetável.Exemplo:
Uso (como um injetável em um controlador)
Uso (a configuração do provedor anterior
$get
é chamada para criar o injetável)fonte
Notei algo interessante ao brincar com os provedores.
A visibilidade dos injetáveis é diferente para os fornecedores e para os serviços e fábricas. Se você declarar uma "constante" AngularJS (por exemplo,
myApp.constant('a', 'Robert');
), poderá injetá-la em serviços, fábricas e fornecedores.Mas se você declarar um "valor" do AngularJS (por exemplo.,
myApp.value('b', {name: 'Jones'});
), Poderá injetá-lo em serviços e fábricas, mas NÃO na função de criação de provedor. No entanto, você pode injetá-lo na$get
função que você define para o seu provedor. Isso é mencionado na documentação do AngularJS, mas é fácil perder. Você pode encontrá-lo na página% de fornecimento nas seções sobre métodos de valor e constante.http://jsfiddle.net/R2Frv/1/
fonte
Esta é uma parte muito confusa para o novato e tentei esclarecê-lo com palavras fáceis
Serviço AngularJS: é usado para compartilhar funções de utilitário com a referência de serviço no controlador. O serviço é de natureza única, portanto, para um serviço, apenas uma instância é criada no navegador e a mesma referência é usada em toda a página.
No serviço, criamos nomes de função como propriedade com este objeto.
AngularJS Factory: o objetivo do Factory também é o mesmo do Service, no entanto, neste caso, criamos um novo objeto e adicionamos funções como propriedades desse objeto e, no final, retornamos esse objeto.
Provedor AngularJS: o objetivo disso é novamente o mesmo, no entanto, o Provedor fornece a saída de sua função $ get.
A definição e o uso de Serviço, Fábrica e Fornecedor são explicados em http://www.dotnetfunda.com/articles/show/3156/difference-between-angularjs-service-factory-and-provider
fonte
Para mim, a melhor e a maneira mais simples de entender a diferença é:
Como o AngularJS instancia componentes específicos (simplificado):
Portanto, para o serviço, o que se torna o componente AngularJS é a instância do objeto da classe que é representada pela função de declaração de serviço. Para a fábrica, é o resultado retornado da função de declaração de fábrica. A fábrica pode se comportar da mesma maneira que o serviço:
A maneira mais simples de pensar é a seguinte:
O exemplo de 'classe' de fábrica é fornecido nos comentários, bem como a diferença de fornecedor.
fonte
new MyService()
ou algo :)Meu esclarecimento sobre este assunto:
Basicamente, todos os tipos mencionados (serviço, fábrica, provedor etc.) estão apenas criando e configurando variáveis globais (que são obviamente globais para todo o aplicativo), exatamente como eram as variáveis globais antiquadas.
Embora as variáveis globais não sejam recomendadas, o uso real dessas variáveis globais é fornecer injeção de dependência , passando a variável para o controlador relevante.
Existem muitos níveis de complicações na criação dos valores para as "variáveis globais":
Define uma constante real que não deve ser modificada durante todo o aplicativo, assim como as constantes em outros idiomas (algo que falta no JavaScript).
Este é um valor ou objeto modificável e serve como alguma variável global, que pode até ser injetada ao criar outros serviços ou fábricas (veja mais adiante). No entanto, ele deve ser um " valor literal ", o que significa que é preciso escrever o valor real e não pode usar nenhuma lógica de computação ou programação (em outras palavras, 39 ou myText ou {prop: "value"} estão OK, mas 2 +2 não é).
Um valor mais geral, que pode ser calculado imediatamente. Ele funciona passando uma função para o AngularJS com a lógica necessária para calcular o valor e o AngularJS o executa e salva o valor de retorno na variável nomeada.
Observe que é possível retornar um objeto (nesse caso, ele funcionará de maneira semelhante a um serviço ) ou uma função (que será salva na variável como uma função de retorno de chamada).
Um serviço é uma versão mais simplificada da fábrica que é válida apenas quando o valor é um objeto e permite gravar qualquer lógica diretamente na função (como se fosse um construtor), além de declarar e acessar as propriedades do objeto usando a palavra - chave this .
Diferente de um serviço que é uma versão simplificada da fábrica , um provedor é uma maneira mais complexa, porém mais flexível, de inicializar as variáveis "globais", com a maior flexibilidade sendo a opção de definir valores no app.config.
Funciona como usar uma combinação de serviço e provedor , passando para o provedor uma função que possui propriedades declaradas usando a palavra - chave this , que pode ser usada no
app.config
.Em seguida, ele precisa ter uma função $ .get separada, que é executada pelo AngularJS após definir as propriedades acima através do
app.config
arquivo, e essa função $ .get se comporta exatamente como a fábrica acima, em que seu valor de retorno é usado para inicializar as variáveis "globais".fonte
Meu entendimento é muito simples abaixo.
Fábrica: você simplesmente cria um objeto dentro da fábrica e o devolve.
Serviço:
Você apenas tem uma função padrão que usa essa palavra-chave para definir uma função.
Fornecedor:
Há um
$get
objeto que você define e pode ser usado para obter o objeto que retorna dados.fonte
Resumo dos documentos angulares :
Melhores respostas de SO:
https://stackoverflow.com/a/26924234/165673 (<- GOOD) https://stackoverflow.com/a/27263882/165673
https://stackoverflow.com/a/16566144/165673
fonte
Todas as boas respostas já. Gostaria de acrescentar mais alguns pontos sobre Serviço e Fábrica . Junto com a diferença entre serviço / fábrica. E também se pode ter perguntas como:
Vamos começar com a diferença entre serviço e fábrica:
Ambos são singletons : sempre que o Angular os encontra como dependência pela primeira vez, ele cria uma única instância de serviço / fábrica. Depois que a instância é criada, a mesma instância é usada para sempre.
Pode ser usado para modelar um objeto com comportamento : ambos podem ter métodos, variáveis de estado interno e assim por diante. Embora a maneira como você escreve esse código seja diferente.
Serviços:
Um serviço é uma função construtora, e o Angular irá instancia-lo chamando new
yourServiceName()
. Isso significa algumas coisas.this
.new yourServiceName(
), ele recebe othis
objeto com todas as propriedades que você coloca nele.Exemplo de exemplo:
Seja cuidadoso com
this
:Como o serviço construído é um objeto, os métodos dentro dele podem se referir a isso quando são chamados:
Você pode ficar tentado a entrar
ScoreKeeper.setScore
em uma cadeia de promessas, por exemplo, se inicializou a pontuação pegando-a no servidor:$http.get('/score').then(ScoreKeeper.setScore).
O problema é queScoreKeeper.setScore
será chamado comthis
vinculadonull
e você obterá erros. A melhor maneira seria$http.get('/score').then(ScoreKeeper.setScore.bind(ScoreKeeper))
. Se você optar por usar isso em seus métodos de serviço ou não, tome cuidado com a forma como os chama.Retornando um valor de
Service
:Devido à maneira como os construtores JavaScript funcionam, se você retornar um valor complexo
(i.e., an Object)
de umaconstructor
função, o chamador obterá esse Objeto em vez da instância.Isso significa que você pode basicamente copiar e colar o exemplo de fábrica abaixo, substituir
factory
porservice
e ele funcionará:Portanto, quando Angular constrói seu serviço com o novo MyService (), ele obtém esse objeto api em vez da instância do MyService.
Esse é o comportamento para quaisquer valores complexos (objetos, funções), mas não para tipos primitivos.
Fábricas:
Uma fábrica é uma função antiga simples que retorna um valor. O valor de retorno é o que é injetado em coisas que dependem da fábrica. Um padrão de fábrica típico em Angular é retornar um objeto com funções como propriedades, assim:
Respostas para as perguntas 1 e 2 acima:
fonte
Um esclarecimento adicional é que as fábricas podem criar funções / primitivas, enquanto os serviços não. Verifique este jsFiddle com base no Epokk: http://jsfiddle.net/skeller88/PxdSP/1351/ .
A fábrica retorna uma função que pode ser chamada:
A fábrica também pode retornar um objeto com um método que pode ser chamado:
O serviço retorna um objeto com um método que pode ser chamado:
Para obter mais detalhes, consulte um post que escrevi sobre a diferença: http://www.shanemkeller.com/tldr-services-vs-factories-in-angular/
fonte
Já existem boas respostas, mas só quero compartilhar essa.
Primeiro de tudo: o provedor é o caminho / receita para criar um
service
(objeto singleton) que deve ser injetado pelo $ injector (como o AngulaJS segue o padrão de IoC).E Valor, Fábrica, Serviço e Constante (4 vias) - o açúcar sintático sobre a maneira / recebimento do Fornecedor .
Não é
Service vs Factory
parte foi coberta: https://www.youtube.com/watch?v=BLzNCkPn3aoO serviço tem tudo a ver com
new
palavras-chave, que, como sabemos, fazem quatro coisas:prototype
objetocontext
athis
this
E Factory é tudo sobre Factory Pattern - contém funções que retornam objetos como esse serviço.
E este vídeo simples / curto: abrange também o provedor : https://www.youtube.com/watch?v=HvTZbQ_hUZY (lá você pode ver como eles vão da fábrica para o fornecedor)
A receita do provedor é usada principalmente na configuração do aplicativo, antes que o aplicativo seja totalmente iniciado / inicializado.
fonte
Depois de ler todos esses posts, criou mais confusão para mim .. Mas ainda assim tudo é informação valiosa .. finalmente encontrei a tabela a seguir que dará informações com comparação simples
E, para iniciantes, entenda: - Isso pode não corrigir o caso de uso, mas em alto nível é o que usamos para esses três.
Para cenários básicos, a fábrica e o serviço se comportam da mesma maneira.
fonte
Aqui está um código que eu criei como um modelo de código para a fábrica de objetos no AngularjS. Eu usei um Car / CarFactory como exemplo para ilustrar. Cria um código de implementação simples no controlador.
Aqui está um exemplo mais simples. Estou usando algumas bibliotecas de terceiros que esperam um objeto "Posição" expondo latitude e longitude, mas através de diferentes propriedades do objeto. Como não queria invadir o código do fornecedor, ajustei os objetos "Posição" que estava passando.
;
fonte
Usando como referência esta página e a documentação (que parece ter melhorado muito desde a última vez que procurei), montei a seguinte demonstração do mundo real (-ish) que usa quatro dos cinco tipos de provedor; Valor, constante, fábrica e fornecedor completo.
HTML:
aplicativo
Demonstração de trabalho .
fonte
Esta resposta aborda o tópico / pergunta
como Factory, Service e Constant - são apenas açúcar sintático em cima de uma receita de provedor?
OU
como fábrica, serviço e fornecedores são semelhantes internamente
basicamente o que acontece é
Quando você
factory()
cria um conjunto de configuraçõesfunction
fornecido no segundo argumento para o provedor$get
e o retorna (provider(name, {$get:factoryFn })
), tudo o que você obtém é queprovider
não há nenhuma propriedade / método além$get
dissoprovider
(significa que você não pode configurar isso)Código fonte da fábrica
Ao fazer um
service()
retorno, você fornece a uma fábrica () umfunction
que injetaconstructor
(retorna a instância do construtor que você forneceu em seu serviço) e o devolveCódigo fonte de serviço
Então, basicamente, em ambos os casos, você eventualmente obtém um conjunto de provedores $ definido para sua função que você forneceu, mas você pode fornecer algo a mais que $ get, como você pode fornecer originalmente no provedor () para o bloco de configuração
fonte
Conheço muitas respostas excelentes, mas tenho que compartilhar minha experiência de usar
1.
service
na maioria dos casos de padrão2.
factory
usado para criar o serviço nessa instância específicae usando:
fonte
Um pouco tarde para a festa. Mas achei que isso seria mais útil para quem gostaria de aprender (ou ter clareza) sobre o desenvolvimento de serviços personalizados JS angulares usando metodologias de fábrica, serviço e provedor.
Encontrei este vídeo que explica claramente sobre as metodologias de fábrica, serviço e provedor para o desenvolvimento de serviços personalizados do AngularJS:
https://www.youtube.com/watch?v=oUXku28ex-M
Código fonte: http://www.techcbt.com/Post/353/Angular-JS-basics/how-to-develop-angularjs-custom-service
O código postado aqui é copiado diretamente da fonte acima, para beneficiar os leitores.
O código para o serviço personalizado baseado em "fábrica" é o seguinte (que acompanha as versões de sincronização e assíncrona, além de chamar o serviço http):
O código para a metodologia "service" para serviços personalizados (isso é bastante semelhante ao 'factory', mas diferente do ponto de vista da sintaxe):
O código da metodologia "provider" para Serviços Personalizados (isso é necessário, se você desejar desenvolver um serviço que possa ser configurado):
Finalmente, a interface do usuário que funciona com qualquer um dos serviços acima:
fonte
Apenas para esclarecer as coisas, na fonte AngularJS, você pode ver um serviço que apenas chama a função de fábrica que, por sua vez, chama a função de provedor:
fonte
Vamos discutir as três maneiras de lidar com a lógica de negócios no AngularJS de uma maneira simples: ( Inspirado no curso Coursera AngularJS do Yaakov )
SERVIÇO :
Sintaxe:
app.js
index.html
Recursos do serviço:
FÁBRICA
Primeiro, vamos dar uma olhada na sintaxe:
app.js :
Agora, usando os dois acima no controlador:
Características da fábrica:
.service()
método é uma fábrica que sempre produz o mesmo tipo de serviço, que é um singleton e sem nenhuma 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.FORNECEDOR
Vamos novamente dar uma olhada na sintaxe primeiro:
Recursos do Provedor:
.service
ou outro.factory
método.$get
é uma função diretamente anexada à instância do provedor. Essa função é uma função de fábrica . Em outras palavras, é exatamente como o que usamos para fornecer ao.factory
método. Nessa função, criamos nosso próprio serviço. Essa$get
propriedade, que é uma função, é o que torna o provedor um provedor . O AngularJS espera que o provedor tenha uma propriedade $ get cujo valor é uma função que o Angular tratará como uma função de fábrica. Mas o que torna toda essa configuração de provedor muito especial é o fato de podermos fornecer algumconfig
objeto dentro do provedor de serviços, e isso geralmente vem com padrões que podemos substituir posteriormente na etapa, onde podemos configurar o aplicativo inteiro.fonte
Fábrica: a fábrica em que você realmente cria um objeto dentro da fábrica e o devolve.
service: o serviço, você apenas possui uma função padrão que usa a palavra-chave this para definir a função.
provider: O provedor tem um $ get you define e pode ser usado para obter o objeto que retorna os dados.
fonte
Essencialmente, Provedor, Fábrica e Serviço são todos Serviços. Um Factory é um caso especial de um Serviço quando tudo o que você precisa é de uma função $ get (), permitindo escrever com menos código.
As principais diferenças entre serviços, fábricas e fornecedores são suas complexidades. Os serviços são a forma mais simples, as fábricas são um pouco mais robustas e os provedores são configuráveis em tempo de execução.
Aqui está um resumo de quando usar cada um:
Fábrica : o valor que você está fornecendo precisa ser calculado com base em outros dados.
Serviço : você está retornando um objeto com métodos.
Fornecedor : você deseja configurar, durante a fase de configuração, o objeto que será criado antes de ser criado. Use o provedor principalmente na configuração do aplicativo, antes que o aplicativo seja totalmente inicializado.
fonte
1. Serviços são objetos únicos que são criados quando necessário e nunca são limpos até o final do ciclo de vida do aplicativo (quando o navegador é fechado). Os controladores são destruídos e limpos quando não são mais necessários.
2. A maneira mais fácil de criar um serviço é usando o método factory (). O método factory () nos permite definir um serviço retornando um objeto que contém funções de serviço e dados de serviço. A função de definição de serviço é onde colocamos nossos serviços injetáveis, como $ http e $ q. Ex:
Usando a factory () em nosso aplicativo
É fácil usar a fábrica em nosso aplicativo, pois podemos simplesmente injetá-lo onde for necessário em tempo de execução.
fonte
Açúcar sintático é a diferença . Somente o provedor é necessário. Ou, em outras palavras, apenas o provedor é o angular real, todos os outros são derivados (para reduzir o código). Também existe uma versão simples, chamada Value (), que retorna apenas o valor, sem cálculo ou função. Even Value é derivado do provedor!
Então, por que essas complicações, por que não podemos simplesmente usar o provedor e esquecer todo o resto? Ele deve nos ajudar a escrever código facilmente e nos comunicar melhor. E a resposta direta seria, quanto mais complexo for, melhor será a venda de uma estrutura.
A injeção angular nos dá a primeira dica para chegar a essa conclusão.
"$ injector é usado para recuperar instâncias de objetos, conforme definido pelo provedor " não pelo serviço, não pela fábrica, mas pelo provedor.
E uma resposta melhor seria a seguinte: "Um serviço Angular é criado por uma fábrica de serviços. Essas fábricas de serviços são funções que, por sua vez, são criadas por um provedor de serviços. Os provedores de serviços são funções construtoras. Quando instanciadas, elas devem conter uma propriedade. chamado $ get, que mantém a função da fábrica de serviços ".
Então, o provedor principal e o injetor e tudo se encaixará :). E fica interessante no Typescript quando $ get pode ser implementado em um provedor, herdando do IServiceProvider.
fonte