Je travaille avec AngularJS pour mon dernier projet. Dans la documentation et les didacticiels, toutes les données de modèle sont placées dans la portée du contrôleur. Je comprends que cela doit être là pour être disponible pour le contrôleur et donc dans les vues correspondantes.
Cependant, je ne pense pas que le modèle devrait réellement être mis en œuvre là-bas. Il peut être complexe et avoir des attributs privés par exemple. De plus, on peut vouloir le réutiliser dans un autre contexte / application. Tout mettre dans le contrôleur rompt totalement le modèle MVC.
Il en va de même pour le comportement de tout modèle. Si j'utilisais l' architecture DCI et un comportement distinct du modèle de données, je devrais introduire des objets supplémentaires pour maintenir le comportement. Cela se ferait en introduisant des rôles et des contextes.
DCI == D ata C ollaboration I nteraction
Bien sûr, les données et le comportement du modèle peuvent être implémentés avec des objets javascript simples ou tout modèle de "classe". Mais quelle serait la façon dont AngularJS le ferait? Vous utilisez des services?
Cela revient donc à cette question:
Comment implémentez-vous des modèles découplés du contrôleur, conformément aux meilleures pratiques AngularJS?
la source
Réponses:
Vous devez utiliser les services si vous voulez quelque chose utilisable par plusieurs contrôleurs. Voici un exemple artificiel simple:
la source
J'essaie actuellement ce modèle, qui, bien que non DCI, fournit un découplage classique de service / modèle (avec des services pour parler aux services Web (aka modèle CRUD), et un modèle définissant les propriétés et méthodes de l'objet).
Notez que j'utilise uniquement ce modèle chaque fois que l'objet modèle a besoin de méthodes travaillant sur ses propres propriétés, que j'utiliserai probablement partout (comme des getter / setters améliorés). Je ne préconise pas de le faire systématiquement pour chaque service.
EDIT: Je pensais que ce modèle irait à l'encontre du mantra "Le modèle angulaire est un vieil objet javascript", mais il me semble maintenant que ce modèle est parfaitement bien.
EDIT (2): Pour être encore plus clair, j'utilise une classe Model uniquement pour factoriser des getters / setters simples (par exemple: à utiliser dans les modèles de vue). Pour la logique des grandes entreprises, je recommande d'utiliser des services distincts qui "connaissent" le modèle, mais qui en sont séparés et qui n'incluent que la logique métier. Appelez cela une couche de service "expert en affaires" si vous le souhaitez
service / ElementServices.js (remarquez comment Element est injecté dans la déclaration)
model / Element.js (en utilisant angularjs Factory, conçu pour la création d'objets)
la source
La documentation d'Angularjs indique clairement:
Cela signifie donc que c'est à vous de déclarer un modèle. C'est un simple objet Javascript.
Personnellement, je n'utiliserai pas les services angulaires car ils étaient censés se comporter comme des objets singleton que vous pouvez utiliser, par exemple, pour conserver des états globaux dans votre application.
la source
DCI est un paradigme et en tant que tel, il n'y a pas de méthode angularJS de le faire, que le langage supporte DCI ou non. JS supporte plutôt bien DCI si vous êtes prêt à utiliser la transformation source et avec quelques inconvénients si vous ne l'êtes pas. Encore une fois, DCI n'a pas plus à voir avec l'injection de dépendances que de dire qu'une classe C # a et n'est certainement pas un service non plus. Donc, la meilleure façon de faire DCI avec angulusJS est de faire DCI à la manière JS, ce qui est assez proche de la façon dont DCI est formulé en premier lieu. Sauf si vous effectuez une transformation source, vous ne pourrez pas le faire complètement car les méthodes de rôle feront partie de l'objet même en dehors du contexte, mais c'est généralement le problème avec l'injection de méthode basée sur DCI. Si vous regardez fullOO.infole site faisant autorité pour DCI, vous pouvez jeter un œil aux implémentations ruby, ils utilisent également l'injection de méthode ou vous pouvez jeter un œil ici pour plus d'informations sur DCI. C'est principalement avec des exemples RUby, mais le contenu DCI est agnostique à cela. L'une des clés de DCI est que ce que fait le système est séparé de ce qu'il est. Ainsi, l'objet de données est assez stupide mais une fois lié à un rôle dans un contexte, les méthodes de rôle rendent certains comportements disponibles. Un rôle est simplement un identifiant, rien de plus, lorsque vous accédez à un objet via cet identifiant, des méthodes de rôle sont disponibles. Il n'y a pas d'objet / classe de rôle. Avec l'injection de méthode, la portée des méthodes de rôle n'est pas exactement telle que décrite mais proche. Un exemple de contexte dans JS pourrait être
la source
Cet article sur les modèles dans AngularJS pourrait aider:
http://joelhooks.com/blog/2013/04/24/modeling-data-and-state-in-your-angularjs-application/
la source
Comme indiqué par d'autres affiches, Angular ne fournit aucune classe de base prête à l'emploi pour la modélisation, mais on peut utilement fournir plusieurs fonctions:
Une bibliothèque qui fait bien toutes ces choses est ngActiveResource ( https://github.com/FacultyCreative/ngActiveResource ). Divulgation complète - j'ai écrit cette bibliothèque - et je l'ai utilisée avec succès dans la création de plusieurs applications à l'échelle de l'entreprise. Il est bien testé et fournit une API qui devrait être familière aux développeurs de Rails.
Mon équipe et moi continuons à développer activement cette bibliothèque, et j'aimerais voir plus de développeurs Angular y contribuer et la tester au combat.
la source
ngActiveResource
et Angular$resource
. Je suis un peu nouveau sur Angular et j'ai parcouru rapidement les deux ensembles de documents, mais ils semblent offrir beaucoup de chevauchements. A éténgActiveResource
développé avant que le$resource
service soit disponible?Une question plus ancienne, mais je pense que le sujet est plus pertinent que jamais étant donné la nouvelle direction d'Angular 2.0. Je dirais qu'une meilleure pratique est d'écrire du code avec le moins de dépendances possible sur un framework particulier. Utilisez uniquement les parties spécifiques du cadre où il ajoute une valeur directe.
Actuellement, il semble que le service Angular soit l'un des rares concepts qui parviendront à la prochaine génération d'Angular, il est donc probablement judicieux de suivre la directive générale de déplacement de toute la logique vers les services. Cependant, je dirais que vous pouvez faire des modèles découplés même sans dépendance directe sur les services angulaires. Créer des objets autonomes avec uniquement les dépendances et les responsabilités nécessaires est probablement la voie à suivre. Cela facilite également la vie lors des tests automatisés. La responsabilité unique est un travail de buzz de nos jours, mais cela a beaucoup de sens!
Voici un exemple de bagout que je considère bon pour découpler le modèle objet du dom.
http://www.syntaxsuccess.com/viewarticle/548ebac8ecdac75c8a09d58e
Un objectif clé est de structurer votre code de manière à le rendre aussi facile à utiliser à partir de tests unitaires qu'à partir d'une vue. Si vous y parvenez, vous êtes bien placé pour écrire des tests réalistes et utiles.
la source
J'ai essayé de résoudre ce problème exact dans ce billet de blog .
Fondamentalement, le meilleur endroit pour la modélisation de données est dans les services et les usines. Cependant, selon la façon dont vous récupérez vos données et la complexité des comportements dont vous avez besoin, il existe de nombreuses façons différentes de procéder à la mise en œuvre. Angular n'a actuellement ni méthode standard ni meilleure pratique.
Le message couvre trois approches, en utilisant $ http , $ resource et Restangular .
Voici un exemple de code pour chacun, avec une
getResult()
méthode personnalisée sur le modèle de Job:Restangulaire (pois facile):
$ ressource (un peu plus alambiquée):
$ http (hardcore):
Le billet de blog lui-même explique plus en détail les raisons pour lesquelles vous pouvez utiliser chaque approche, ainsi que des exemples de code sur la façon d'utiliser les modèles dans vos contrôleurs:
Modèles de données AngularJS: $ http VS $ resource VS Restangular
Il est possible qu'Angular 2.0 offre une solution plus robuste à la modélisation des données qui rassemble tout le monde sur la même page.
la source