AngularJS: Comprendre le modèle de conception
Dans le contexte de ce post par Igor Minar, le plomb de AngularJS:
MVC vs MVVM vs MVP. Ce qu'est un sujet controversé que de nombreux développeurs
vous pouvez passer des heures et des heures à débattre et à argumenter à propos.Depuis plusieurs années AngularJS était plus proche de MVC (ou plutôt l'un de ses
côté client variantes), mais au fil du temps et grâce à de nombreux refactorings
d'api et d'améliorations, il est maintenant plus proche de MVVM – le $portée objet
pourrait être considéré comme le ViewModel qui est décoré par un
la fonction que nous appelons un Contrôleur.Être en mesure de catégoriser un cadre et de le placer dans l'un des MV* seaux a certains avantages.
Il peut aider les développeurs à obtenir plus à l'aise avec ses api en le rendant
plus facile de créer un modèle mental qui représente l'application que
se construit avec le cadre. Il peut aussi aider à établir
la terminologie qui est utilisée par les développeurs.L'avoir dit, je préfère voir les développeurs à créer de kick-ass, les applications qui sont
bien conçu et suivez la séparation des préoccupations, que de les voir déchets
de temps à discuter sur MV* non-sens. Et pour cette raison, je déclare par la présente
AngularJS être MVW cadre - Modèle-Vue-ce que. Où Tout Ce Que
signifie "tout ce qui fonctionne pour vous".Angulaire vous donne beaucoup de flexibilité, afin de bien séparer la présentation
la logique de la logique métier et la présentation de l'état. Veuillez utiliser le carburant
votre productivité et la maintenabilité de l'application plutôt que d'chauffée
les discussions à propos de choses qu'à la fin de la journée, n'a pas d'importance qui
beaucoup.
Sont là des recommandations ou des lignes directrices pour la mise en œuvre AngularJS MVW (Modèle-Vue-ce que) modèle de conception dans des applications côté client?
- upvoted pour ..., que de les voir perdre du temps à se disputer sur MV* non-sens.
- Vous n'avez pas besoin Angulaire de suivre un mot de la classe de modèle de conception.
Vous devez vous connecter pour publier un commentaire.
Grâce à une énorme quantité de précieuses sources, j'ai quelques recommandations générales pour la mise en œuvre de composants dans les applications AngularJS:
Contrôleur de
Contrôleur doit être juste un intercalaire entre le modèle et la vue. Essayer de le faire, mince que possible.
Il est fortement recommandé de éviter la logique métier dans le contrôleur. Il doit être déplacé pour modèle.
Contrôleur peut communiquer avec d'autres contrôleurs à l'aide de la méthode d'invocation (possible lorsque les enfants veut communiquer avec un parent) ou $émettent, $de diffusion et $sur méthodes. Émis et diffusé les messages doivent être maintenus à un minimum.
Contrôleur doit soucient pas de la présentation ou de manipulation du DOM.
Essayer de éviter imbriqués les contrôleurs de. Dans ce cas, contrôleur de parent est interprété comme modèle. Injecter des modèles de services partagés de la place.
Portée dans le contrôleur doit être utilisé pour liaison modèle avec vue et
l'encapsulation Modèle de Vue comme pour Modèle de Présentation motif de conception.
Portée
Traiter portée en lecture seule dans les modèles et en écriture seulement dans les contrôleurs. Le but de la portée est de se référer au modèle, de ne pas être le modèle.
Lors bidirectionnel de liaison (ng-model) assurez-vous de ne pas lier directement à la portée des propriétés.
Modèle
Modèle dans AngularJS est un singleton défini par service.
Modèle fournit un excellent moyen pour séparer les données et de les afficher.
Modèles sont les premiers candidats pour les tests unitaires, comme ils ont généralement exactement une dépendance (une forme de manifestation de l'émetteur, dans le cas de la $rootScope) et contiennent très testable domaine de la logique.
Modèle doit être considéré comme une mise en place de l'unité en question.
Elle est basée sur une seule responsabilité de principe. L'unité est une instance qui est responsable de son propre champ d'application de la logique que peut représenter la seule entité dans le monde réel et le décrire dans le monde de programmation en termes de de données et de l'état.
Modèle doit encapsuler les données de votre application et de fournir un API
pour accéder et manipuler des données.
Modèle devrait être portable de sorte qu'il peut facilement être transporté sur similaires
application.
Par l'isolement de l'unité logique dans votre modèle, vous ont rendu plus facile
les localiser, de les mettre à jour et conserver.
Modèle peut utiliser des méthodes plus générales sur les modèles globaux qui sont communes
pour l'ensemble de l'application.
Essayez d'éviter de composition d'autres modèles dans votre modèle à l'aide de l'injection de dépendance si elle n'est pas vraiment dépendant de la diminution de composants de couplage et de l'unité de multiplication testabilité et convivialité.
Essayez d'éviter d'utiliser des écouteurs d'événement dans les modèles. Il les rend plus difficiles à tester et généralement tue des modèles en termes de la seule responsabilité de principe.
Mise En Œuvre Du Modèle
Comme modèle doit encapsuler la logique en termes de données et de l'état, il devrait l'architecture de restreindre l'accès à ses membres ainsi nous pouvons garantir le couplage lâche.
La manière de le faire en application AngularJS est de la définir à l'aide de usine type de service. Cela va nous permettre de définir des propriétés privées et des méthodes très facile et aussi de retour publiquement accessibles dans le seul endroit qui le rendra vraiment lisible pour le développeur.
Un exemple:
La création de nouvelles instances
Essayez d'éviter d'avoir une usine qui renvoie une nouvelle mesure de fonction comme cela commence à décomposer l'injection de dépendance et de la bibliothèque va se comporter maladroitement, en particulier pour les tiers.
Une meilleure façon d'accomplir la même chose est d'utiliser de l'usine comme une API pour retourner une collection d'objets avec des méthodes getter et setter attaché à eux.
Modèle Global
En général, essayez d'éviter de telles situations et la conception de vos modèles correctement donc il peut être injecté dans le contrôleur et utilisés dans votre point de vue.
Dans le cas particulier de certaines méthodes nécessitent l'accessibilité globale à l'intérieur de l'application.
Pour la rendre possible, vous pouvez définir la " commune propriété $rootScope et le lier à commonModel lors de l'application de bootstrap:
Toutes vos méthodes globales vivent à moins de ‘commune la propriété. C'est une sorte de espace de noms.
Mais ne définit pas de méthodes directement dans votre $rootScope. Cela peut conduire à un comportement inattendu lorsqu'il est utilisé avec ngModel la directive au sein de votre portée de vue, généralement jonchent votre portée et conduit à la portée des méthodes de questions primordiales.
Ressources
De ressources vous permet d'interagir avec différents sources de données.
Devraient être mises en œuvre à l'aide de seule responsabilité de principe.
Dans le cas particulier, il est un réutilisables proxy HTTP/JSON points de terminaison.
Ressources sont injectées dans les modèles et assurer la possibilité d'envoyer et de récupérer des données.
De ressources de mise en œuvre
Une usine qui crée un objet de ressource qui vous permet d'interagir avec RESTful côté serveur des sources de données.
Le retour de l'objet de la ressource a des méthodes d'action qui fournissent de haut niveau des comportements, sans la nécessité d'interagir avec le faible niveau de $service http.
Services
À la fois modèle et des ressources sont des services.
Services non liés, faiblement couplé unités de fonctionnalités qui sont autonomes.
Services sont une fonctionnalité qui Angulaire apporte à côté client applications web côté serveur, où les services ont été couramment utilisés pendant une longue période.
Services Angulaire applications sont substituables les objets qui sont fixés ensemble à l'aide de l'injection de dépendance.
Angulaire est livré avec différents types de services. Chacun avec son propre cas d'utilisation. Veuillez lire Comprendre Les Types De Services De pour plus de détails.
Essayez de tenir compte de les grands principes de l'architecture de services dans votre application.
En général selon Services Web Glossaire:
Côté Client, structure
En général partie client de l'application est découpée en modules. Chaque module doit être testable comme une unité.
Essayer de définir les modules en fonction de fonction/fonctionnalités ou vue, non pas par type.
Voir Misko présentation pour plus de détails.
Des composants du Module peut être classiquement regroupés par types, tels que les contrôleurs, les modèles, les vues, les filtres, directives, etc.
Mais le module en lui-même reste réutilisables, transférables et testable.
Il est aussi beaucoup plus facile pour les développeurs de trouver certaines parties de code et de toutes ses dépendances.
Veuillez vous référer à Code de l'Organisation dans les Grandes AngularJS et des Applications JavaScript pour plus de détails.
Un exemple de dossiers structurants:
Bon exemple de l'angulaire de l'application de structuration est mis en œuvre par angulaires-app - https://github.com/angular-app/angular-app/tree/master/client/src
Ceci est également considéré par l'application moderne générateurs - https://github.com/yeoman/generator-angular/issues/109
searchModel
ne suit pas la ré-utilisabilité des conseils. Il serait mieux à l'importation les constantes via lesconstant
service. 3. Aucune explication de ce qui est signifié ici?:Try to avoid having a factory that returns a new able function
prototype
propriété des sauts de l'héritage, au lieu de cela, on peut utiliserCar.prototype.save = ...
object
dans votre liaison bidirectionnelle expression assurez-vous d'écrire à la propriété exacte ousetter
fonction. Dans le cas de l'utilisation directe de la propriété de votre portée (sans un point), vous avez un risque de masquer l'objectif souhaité de la propriété avec le nouvellement créé un la plus proche de la partie supérieure de la portée dans la chaîne de prototype lors de la rédaction de elle. C'est mieux expliqué dans Misko de présentationcar.save()
au sein d'un modèle de l'objet, mais ce qui se passe si l'enregistrement échoue? Est-ce vraiment le modèle qui doit gérer cela? Après tout,save()
est juste un moyen d'atteindre le serveur, ne faisant pas partie du domaine de la logique - c'est la logique de l'application, ce qui nécessite un calque distinct. Voir ma réponse plus.Je crois Igor prendre à ce sujet, comme on le voit dans la citation que vous avez fournies, c'est juste la pointe d'un iceberg beaucoup plus de problème.
MVC et de ses dérivés (MVP, PM, MVVM) sont tous bons et dandy au sein d'un seul agent, mais un serveur architecture client est, à toutes fins, de deux agents du système, et les gens sont tellement obsédés par ces motifs qu'ils oublient que le problème est beaucoup plus complexe. En essayant de respecter ces principes, ils effectivement se retrouver avec une mauvaise architecture.
Faisons ce bit par bit.
Les lignes directrices
Vues
Dans Angulaire contexte, le point de vue est le DOM. Les lignes directrices sont les suivantes:
Faire:
N'est pas le cas:
Tentant, court, et sans danger, cela ressemble:
Très bien signifier tout développeur qui maintenant à comprendre comment le système de travail dont ils ont besoin pour inspecter les fichiers Javascript et le HTML.
Contrôleurs
Faire:
N'est pas le cas:
La raison de la dernière directive est que les contrôleurs sont sœurs de vues, et non des entités; ni ils sont réutilisables.
On peut dire que les directives sont réutilisables, mais les directives sont trop sœurs de vues (DOM) - ils n'ont pas été conçus pour correspondre à des entités.
Sûr, parfois vues représentent des entités, mais c'est plutôt un cas particulier.
En d'autres termes, les contrôleurs doivent se concentrer sur la présentation - si vous jetez à la logique métier dans les, non seulement vous êtes susceptibles de se retrouver avec un gonflés, petit-gestion contrôleur, mais vous aussi violer la séparation des préoccupations principe.
En tant que tel, les contrôleurs Angulaire sont vraiment de plus de Modèle de Présentation ou MVVM.
Et donc, si les contrôleurs ne doit pas traiter avec une logique d'entreprise, qui devrait?
Qu'est ce qu'un modèle?
Votre modèle client est souvent partielle et obsolètes
À moins que vous écrivez hors connexion d'une application web, ou une application qui est terriblement simple (quelques unités), vous modèle client est très susceptible d'être:
Le modèle réel doit persister
Traditionnelle MCV, le modèle est la seule chose persisté. Chaque fois que nous parlons de modèles, celle-ci doit être conservé à un certain point. Votre client peut manipuler des modèles à volonté, mais jusqu'à ce que l'aller-retour vers le serveur a été achevée avec succès, le travail n'est pas terminé.
Conséquences
Les deux points ci-dessus doit servir de mise en garde - le modèle de votre client peut impliquer une partielle, pour la plupart simples de la logique métier.
En tant que tel, il est peut-être sage, à l'intérieur du contexte client, à utiliser des minuscules
M
- donc, c'est vraiment mVC, mVP, et mVVm. Le grandM
est pour le serveur.Logique d'entreprise
Peut-être l'un des concepts les plus importants sur modèles d'affaires, c'est que vous pouvez subdiviser à 2 types (je n'omettez le troisième vue-business, car c'est une histoire pour un autre jour):
firstName
etsirName
propriétés, un getter commegetFullName()
peut être considérée comme indépendante des applications.Il est important de souligner que ces deux à l'intérieur d'un contexte client sont pas de "vrais" logique d'entreprise - ils ne concernent que la partie de ce qui est important pour le client. La logique de l'Application (pas de domaine logique) ont la responsabilité de faciliter la communication avec le serveur et la plupart d'interaction de l'utilisateur; tandis que la logique de domaine est en grande partie à petite échelle, propre à l'entité, et la présentation axée sur le marché.
La question reste encore - où voulez-vous de les jeter dans angulaire de l'application?
3 vs 4 couches de l'architecture
Tous ces MVW des cadres utilisation de 3 couches:
Mais il y a deux questions fondamentales avec cela quand il s'agit de clients:
Une alternative à cette stratégie est la 4 couche de stratégie:
La vraie affaire ici est la couche de règles d'affaires (cas d'Utilisation), qui va souvent de mal sur les clients.
Cette couche est réalisée par des interacteurs (Oncle Bob), qui est à peu près ce que Martin Fowler appelle une fonctionnement du script de la couche de service.
Exemple concret
Envisager les applications web suivants:
Un peu les choses devraient se passer maintenant:
Où en sommes-nous jeter tout cela?
Si votre architecture comporte un contrôleur qui appelle
$resource
, tout cela se passera dans le contrôleur. Mais il y a une meilleure stratégie.Une solution proposée
Le diagramme suivant montre comment le problème ci-dessus peut être résoudre par l'ajout d'une autre application de la couche logique Angulaire clients:
Nous avons donc ajouter une couche entre le contrôleur de dollars de ressources, cette couche (appelons cela interacteur):
UserInteractor
.Et donc, avec les exigences de l'exemple concret ci-dessus:
validate()
validate()
méthode.createUser()
If failed, the controller handles the error.
- comment un contrôleur de savoir si lavalidate()
méthode provient d'un service d'Application (Logique)?validate()
méthode. Ainsi, le contrôleur peut encore appelervalidate()
et vérifier de quoi il en retourne. La validation est dans le modèle, pas le service; le service ajoute au prototype.Un problème mineur en comparaison des grands conseils dans l'Art de la réponse, mais en termes de lisibilité du code, j'ai trouvé préférable de définir l'API complètement à l'intérieur de la
return
objet, afin de minimiser les va-et-vient dans le code wheverer variables sont définies:Si le
return
objet devient à la recherche "trop de monde", ce qui est un signe que le Service est d'en faire trop.AngularJS fais pas de mettre en œuvre MVC de façon traditionnelle, c'est plutôt elle met en œuvre quelque chose de plus MVVM(Model-View-ViewModel), ViewModel peut également être désigné comme liant(angulaire cas, il peut être de portée).
Le Modèle--> Comme nous le savons modèle angulaire peut être juste un bon vieux objets JS ou les données dans notre application
L'Affichage--> le point de vue dans angularJS est le code HTML qui a été analysé et compilé par angularJS par l'application des directives ou des instructions ou des liaisons point Principal ici, c'est dans angulaire de l'entrée n'est pas seulement l'HTML simple chaîne de caractères(innerHTML), c'est plutôt DOM créé par navigateur.
Le ViewModel--> ViewModel est en fait le liant/pont entre votre modèle et de la vue dans angularJS cas, il est de portée, d'initialiser et d'augmenter l' $champ d'application, nous utilisons Contrôleur.
Si je veux résumer la réponse: En application angularJS $champ d'application de référence pour les données, le Contrôleur contrôle le comportement, et d'Afficher les poignées de la mise en interagissant avec le contrôleur à se comporter en conséquence.
À être croustillante à propos de la question, Angulaire utilise différents modèles de conception que nous avons déjà rencontrées dans notre programmation régulière.
1) Quand on enregistre nos contrôleurs ou des directives, l'usine, les services, etc à l'égard de notre module. Ici, c'est de cacher les données à partir de l'espace mondial. Qui est motif de Module.
2) Lorsque angulaire utilise son sale de vérifier pour la comparaison de la portée des variables, ici, il utilise Pattern observer.
3) le parent de l'enfant étendues dans nos contrôleurs utilise Prototypes modèle.
4) Dans le cas de l'injection les services qu'il utilise Modèle de Fabrique.
L'ensemble, il utilise différents connu des modèles de conception pour résoudre les problèmes.