O AngularJS afirma claramente em sua documentação que os Serviços são Singletons:
AngularJS services are singletons
Contra-intuitivamente, module.factory
também retorna uma instância de Singleton.
Dado que há muitos casos de uso para serviços não singleton, qual é a melhor maneira de implementar o método de fábrica para retornar instâncias de um serviço, de modo que cada vez que uma ExampleService
dependência é declarada, ela é satisfeita por uma instância diferente de ExampleService
?
Respostas:
Eu não acho que deveríamos ter uma fábrica retornando uma
new
função capaz, pois isso começa a quebrar a injeção de dependência e a biblioteca se comportará de maneira estranha, especialmente para terceiros. Resumindo, não tenho certeza se há casos de uso legítimos para serviços não singleton.A melhor maneira de realizar a mesma coisa é usar a fábrica como uma API para retornar uma coleção de objetos com métodos getter e setter anexados a eles. Aqui está um pseudo-código que mostra como usar esse tipo de serviço pode funcionar:
Este é apenas um pseudocódigo para procurar um widget por ID e, em seguida, ser capaz de salvar as alterações feitas no registro.
Aqui estão alguns pseudocódigos para o serviço:
Embora não estejam incluídos neste exemplo, esses tipos de serviços flexíveis também podem gerenciar facilmente o estado.
Não tenho tempo agora, mas se for útil, posso montar um Plunker simples mais tarde para demonstrar.
fonte
$resource
.Não tenho certeza de qual caso de uso você está tentando satisfazer. Mas é possível que uma fábrica retorne instâncias de um objeto. Você deve ser capaz de modificar isso para atender às suas necessidades.
JsFiddle
Atualizada
Considere a seguinte solicitação para serviços não singleton . Em que Brian Ford observa:
e seu exemplo de retorno de instâncias de fábricas:
Eu também diria que seu exemplo é superior devido ao fato de que você não precisa usar a
new
palavra - chave em seu controlador. Ele é encapsulado nogetInstance
método do serviço.fonte
ngInfiniteScroll
um serviço de pesquisa personalizado para que possa atrasar a inicialização até algum evento de clique. JSFiddle da 1ª resposta atualizado com a segunda solução: jsfiddle.net/gavinfoley/G5ku5new
é declarativo e é fácil dizer imediatamente quais serviços são singleton e quais não são. Com base em se um objeto está sendo atualizado.Outra maneira é copiar o objeto de serviço com
angular.extend()
.e então, por exemplo, em seu controlador
Aqui está um golpe .
fonte
Sei que esta postagem já foi respondida, mas ainda acho que haveria alguns cenários legítimos em que você precisa para ter um serviço não único. Digamos que haja alguma lógica de negócios reutilizável que pode ser compartilhada entre vários controladores. Nesse cenário, o melhor lugar para colocar a lógica seria um serviço, mas e se precisarmos manter algum estado em nossa lógica reutilizável? Então, precisamos de um serviço não único para que possa ser compartilhado entre diferentes controladores no aplicativo. É assim que eu implementaria esses serviços:
fonte
Aqui está meu exemplo de um serviço não singleton, é de um ORM em que estou trabalhando. No exemplo, mostro um modelo básico (ModelFactory) que desejo que os serviços ('usuários', 'documentos') herdem e possam estender.
No meu ORM, o ModelFactory injeta outros serviços para fornecer funcionalidade extra (consulta, persistência, mapeamento de esquema) que é colocado em sandbox usando o sistema de módulo.
No exemplo, o usuário e o serviço de documentos têm a mesma funcionalidade, mas têm seus próprios escopos independentes.
fonte
angular só dá um singleton opção de serviço / fábrica. uma maneira de contornar isso é ter um serviço de fábrica que criará uma nova instância para você dentro de seu controlador ou outras instâncias de consumidor. a única coisa que é injetada é a classe que cria novas instâncias. este é um bom lugar para injetar outras dependências ou para inicializar seu novo objeto com a especificação do usuário (adicionando serviços ou configuração)
então, em sua instância de consumidor, você precisa do serviço de fábrica e chama o método de construção na fábrica para obter uma nova instância quando precisar
você pode ver que ele fornece oportunidade para injetar alguns serviços específicos que não estão disponíveis na etapa de fábrica. você sempre pode fazer a injeção acontecer na instância de fábrica para ser usada por todas as instâncias de Model.
Note que tive que retirar algum código, então posso cometer alguns erros de contexto ... se você precisar de um exemplo de código que funcione, me avise.
Acredito que NG2 terá a opção de injetar uma nova instância de seu serviço no lugar certo em seu DOM, de forma que você não precise construir sua própria implementação de fábrica. Vai ter que esperar e ver :)
fonte
Acredito que haja um bom motivo para criar uma nova instância de um objeto dentro de um serviço. Devemos manter a mente aberta também, em vez de apenas dizer que nunca devemos fazer tal coisa, mas o singleton foi feito assim por uma razão . Os controladores são criados e destruídos frequentemente durante o ciclo de vida do aplicativo, mas os serviços devem ser persistentes.
Posso pensar em um caso de uso em que você tem um fluxo de trabalho de algum tipo, como aceitar um pagamento e tem várias propriedades definidas, mas agora deve alterar o tipo de pagamento porque o cartão de crédito do cliente falhou e ele precisa fornecer uma forma diferente de Forma de pagamento. Claro, isso tem muito a ver com a maneira como você cria seu aplicativo. Você pode redefinir todas as propriedades do objeto de pagamento ou pode criar uma nova instância de um objeto dentro do serviço . Porém, você não deseja uma nova instância do serviço, nem deseja atualizar a página.
Acredito que uma solução é fornecer um objeto dentro do serviço que você pode criar uma nova instância e definir. Mas, só para ficar claro, a única instância do serviço é importante porque um controlador pode ser criado e destruído muitas vezes, mas os serviços precisam de persistência. O que você está procurando pode não ser um método direto no Angular, mas um padrão de objeto que você pode gerenciar dentro do seu serviço.
Por exemplo, fiz um botão de reset . (Isso não foi testado; na verdade, é apenas uma ideia rápida de um caso de uso para a criação de um novo objeto dentro de um serviço.
fonte
Aqui está outra abordagem para o problema com a qual fiquei bastante satisfeito, especificamente quando usado em combinação com o Closure Compiler com otimizações avançadas habilitadas:
fonte