Estou trabalhando com o AngularJS para o meu projeto mais recente. Na documentação e nos tutoriais, todos os dados do modelo são colocados no escopo do controlador. Eu entendo que é preciso estar lá para estar disponível para o controlador e, portanto, dentro das visualizações correspondentes.
No entanto, acho que o modelo não deve ser implementado lá. Pode ser complexo e ter atributos particulares, por exemplo. Além disso, pode-se querer reutilizá-lo em outro contexto / aplicativo. Colocar tudo no controlador quebra totalmente o padrão MVC.
O mesmo vale para o comportamento de qualquer modelo. Se eu usasse a arquitetura DCI e separasse o comportamento do modelo de dados, teria que introduzir objetos adicionais para manter o comportamento. Isso seria feito através da introdução de papéis e contextos.
DCI == D ATA C OLABORAÇÃO eu nteração
Obviamente, os dados e o comportamento do modelo podem ser implementados com objetos javascript simples ou qualquer padrão de "classe". Mas qual seria a maneira do AngularJS fazer isso? Usando serviços?
Então, tudo se resume a esta pergunta:
Como você implementa modelos dissociados do controlador, seguindo as práticas recomendadas do AngularJS?
fonte
Respostas:
Você deve usar serviços se quiser algo utilizável por vários controladores. Aqui está um exemplo simples e artificial:
fonte
Atualmente, estou tentando esse padrão, que, embora não seja o DCI, fornece um desacoplamento clássico de serviço / modelo (com serviços para conversar com serviços da web (também conhecido como modelo CRUD) e modelo que define as propriedades e métodos do objeto).
Observe que eu só uso esse padrão sempre que o objeto de modelo precisar de métodos trabalhando em suas próprias propriedades, que provavelmente usarei em qualquer lugar (como getter / setters aprimorados). Estou não defendendo fazendo isso por todos os serviços de forma sistemática.
Edição: Eu costumava pensar que esse padrão iria contra o mantra "modelo angular é simples objeto javascript antigo", mas parece-me agora que esse padrão está perfeitamente bem.
EDIT (2): Para ser mais claro, eu uso uma classe Model apenas para fatorar getters / setters simples (por exemplo: para serem usados em modelos de exibição). Para a lógica de grandes negócios, recomendo o uso de serviços separados que "conhecem" o modelo, mas são mantidos separados deles e incluem apenas a lógica de negócios. Chame de camada de serviço "especialista em negócios", se desejar
service / ElementServices.js (observe como o Element é injetado na declaração)
model / Element.js (usando o angularjs Factory, criado para criação de objeto)
fonte
A documentação do Angularjs afirma claramente:
Então, isso significa que você decide como declarar um modelo. É um simples objeto Javascript.
Pessoalmente, não utilizarei os Serviços Angular, pois eles deveriam se comportar como objetos singleton que você pode usar, por exemplo, para manter estados globais em seu aplicativo.
fonte
O DCI é um paradigma e, como tal, não existe uma maneira angular do JS de fazê-lo, o idioma suporta o DCI ou não. JS suporta DCI bastante bem se você estiver disposto a usar a transformação de origem e, com algumas desvantagens, se não estiver. Novamente, o DCI não tem mais a ver com injeção de dependência do que dizer que uma classe C # tem e definitivamente também não é um serviço. Portanto, a melhor maneira de fazer o DCI com o angulusJS é fazê-lo da maneira JS, o que é bem próximo de como o DCI é formulado em primeiro lugar. A menos que você faça a transformação de origem, você não poderá executá-lo totalmente, pois os métodos de função farão parte do objeto mesmo fora do contexto, mas esse geralmente é o problema com o DCI baseado em injeção de método. Se você olhar para fullOO.infoNo site oficial do DCI, você pode dar uma olhada nas implementações do ruby, elas também usam injeção de método ou você pode dar uma olhada aqui para obter mais informações sobre o DCI. É principalmente com exemplos de RUby, mas o material DCI é independente disso. Uma das chaves do DCI é que o que o sistema faz é separado do que é o sistema. Portanto, o objeto de dados é bastante tolo, mas uma vez vinculado a uma função em um contexto, os métodos de função disponibilizam determinado comportamento. Uma função é simplesmente um identificador, nada mais, e ao acessar um objeto através desse identificador, os métodos de função estão disponíveis. Não há nenhum objeto / classe de função. Com a injeção de método, o escopo dos métodos de função não é exatamente como descrito, mas aproximado. Um exemplo de contexto em JS pode ser
fonte
Este artigo sobre modelos no AngularJS pode ajudar:
http://joelhooks.com/blog/2013/04/24/modeling-data-and-state-in-your-angularjs-application/
fonte
Conforme declarado em outros pôsteres, o Angular não fornece classe básica pronta para modelagem, mas é possível fornecer várias funções de maneira útil:
Uma biblioteca que faz todas essas coisas bem é o ngActiveResource ( https://github.com/FacultyCreative/ngActiveResource ). Divulgação completa - escrevi esta biblioteca - e usei-a com sucesso na criação de vários aplicativos em escala corporativa. É bem testado e fornece uma API que deve ser familiar para os desenvolvedores do Rails.
Minha equipe e eu continuamos desenvolvendo ativamente essa biblioteca e adoraria ver mais desenvolvedores Angular contribuindo e testando a batalha.
fonte
ngActiveResource
e o$resource
serviço da Angular . Sou um pouco novo no Angular e naveguei rapidamente nos dois conjuntos de documentos, mas eles parecem oferecer muita sobreposição. FoingActiveResource
desenvolvido antes da$resource
disponibilidade do serviço?Uma pergunta mais antiga, mas acho que o tópico é mais relevante do que nunca, dada a nova direção do Angular 2.0. Eu diria que uma prática recomendada é escrever código com o mínimo de dependências possível em uma estrutura específica. Use apenas as partes específicas da estrutura em que agrega valor direto.
Atualmente, parece que o serviço Angular é um dos poucos conceitos que chegarão à próxima geração do Angular, por isso é provavelmente inteligente seguir a diretriz geral de mover toda a lógica para os serviços. No entanto, eu argumentaria que você pode criar modelos dissociados, mesmo sem uma dependência direta dos serviços Angular. Criar objetos independentes com apenas dependências e responsabilidades necessárias é provavelmente o caminho a percorrer. Também facilita muito a vida ao realizar testes automatizados. Nos dias de hoje, a responsabilidade única é um trabalho movimentado, mas faz muito sentido!
Aqui está um exemplo de um padrão que considero bom para dissociar o modelo de objeto do dom.
http://www.syntaxsuccess.com/viewarticle/548ebac8ecdac75c8a09d58e
Um dos principais objetivos é estruturar seu código de maneira a torná-lo tão fácil de usar em testes de unidade quanto em uma exibição. Se você conseguir isso, estará bem posicionado para escrever testes realistas e úteis.
fonte
Eu tentei resolver esse problema exato nesta postagem do blog .
Basicamente, o melhor local para modelagem de dados é em serviços e fábricas. No entanto, dependendo de como você recupera seus dados e da complexidade dos comportamentos necessários, existem várias maneiras diferentes de executar a implementação. Angular atualmente não possui padrão maneira ou uma melhor prática.
A publicação aborda três abordagens, usando $ http , $ resource e Restangular .
Aqui está um exemplo de código para cada um, com um
getResult()
método personalizado no modelo de trabalho:Restangular (fácil camurça):
$ resource (um pouco mais complicado):
$ http (incondicional):
A postagem do blog detalha o motivo por que você pode usar cada abordagem, bem como exemplos de código de como usar os modelos em seus controladores:
Modelos de dados AngularJS: $ http VS $ resource VS Restangular
Existe a possibilidade do Angular 2.0 oferecer uma solução mais robusta para modelagem de dados que coloca todos na mesma página.
fonte