71 votes

Où le modèle doit-il être stocké dans Angular.js

Je suis la recherche Angulaire de l'utilisation de modèles à confusion. Angulaire semble prendre l'approche d'un modèle peut être quelque chose que vous aimez - I. E. Angulaire ne comprend pas un modèle explicite de la classe et vous pouvez utiliser de la vanille des objets JavaScript, comme des modèles.

Dans presque tous Angulaire exemple que j'ai vu, le modèle est effectivement un objet, soit créés par la main, ou retourné par un appel d'API par l'intermédiaire d'une Ressource. Parce que presque tous Angulaire exemple, que j'ai regardé est simple, généralement le modèle de données stockées sur $portée dans un contrôleur, et à tout etat liées à la le modèle, par exemple la sélection, sont également stockées sur la somme portée dans le contrôleur. Cela fonctionne très bien pour des applications simples et des exemples, mais cela semble être une simplification excessive lorsque les applications deviennent plus complexes. Modèle de l'état stocké dans un contrôleur est à risque de le devenir contextuelles et d'être perdues si le contexte change, par exemple, Un Contrôleur de stockage selectedGallery et selectedPhoto ne peut stocker que de global selectedImage, pas un selectedPhoto par galerie. Dans une telle situation, l'utilisation d'un contrôleur par galerie peut nier ce problème, mais semble inutile et probablement inapproprié et inutile d'un point de vue de l'INTERFACE utilisateur.

Angulaire de la définition de modèles semble plus proche de ce que je considère comme un VO/DTO qui est un muet objet passé entre le serveur et le client. Mon instinct est d'envelopper un tel objet dans ce que je considère comme un Modèle - une classe qui gère l'état relatives à la DTO/VO (comme la sélection), propose des mutateurs que nécessaire pour manipuler les DTO/VO, et en informe le reste de l'application des modifications aux données sous-jacentes. Évidemment, cette dernière partie est très bien pris en charge par Angulaire de liaisons, mais je vois encore une forte cas d'utilisation pour les deux premières responsabilités.

Cependant, je n'ai pas vraiment vu ce motif est utilisé dans les exemples que j'ai regardé, mais je n'ai pas vu ce que je considère être une solution évolutive alternative. Angulaire semble implicitement décourager l'utilisation de Services comme des modèles par l'application de Singletons (je sais qu'il ya des façons de contourner cela, mais ils ne semblent pas largement utilisés ou approuvé).

Alors, comment devrais-je conserver l'état sur le Modèle de données?

[Modifier] La deuxième réponse à cette question est intéressante et proche de ce que je suis en train d'utiliser.

28voto

superluminary Points 5496

L'etat (et modèles) sont stockés dans $portée

$champ d'application est un objet défini et mis à jour pour vous par Angulaire. $champ d'application est liée à la DOM, donc si vous dites à un particulier partie du DOM utilisation d'un contrôleur, une nouvelle $champ d'application objet sera créé, lié à la partie de la DOM, et puis éventuellement transmis au contrôleur qui va initialiser.

Le but du régulateur est d'initialiser $champ d'application. Le même contrôleur peut initialiser beaucoup de $objets de portée dans les différentes parties de la page. Le contrôleur exécute une fois, met en place l' $objet de l'étendue et puis quitte. Vous pouvez utiliser le même contrôleur pour initialiser beaucoup de $étendues dans les différentes parties de la page.

Dans le cas de votre galerie d'images, vous avez une imageGallery contrôleur qui vous serait alors s'appliquent à chaque partie du DOM qui vous voulez être une galerie à l'aide de la ng-controller directive. La partie de la page c'est faire le propre de $la portée, ce qui vous permet de stocker les selectedPhoto attribut.

$portée hérite de son parent à l'aide de la plaine vieil héritage par prototype tout le chemin jusqu'à $rootScope, de sorte que vous pouvez stocker vos objets n'importe où sur la hiérarchie qui fait sens. Vous obtenez un arbre de $portée des objets à peu près se rapporte à votre DOM. Si votre DOM changements, la nouvelle $portée les objets sont créés pour vous.

$champ d'application est juste un simple objet JavaScript. Ce n'est plus une perte de temps de créer plusieurs $portée des objets, plutôt que de créer un tableau avec plusieurs currentImage objets.

De cette façon Angulaire de l'ancien "où dois-je conserver mes données" problème que nous trouvons souvent en JavaScript. C'est la source de l'un des très grands gains de productivité que nous obtenons à partir Angulaire.

Obtenu les données globales (par exemple. un nom d'utilisateur)? magasin sur $rootScope. A obtenu des données locales (par exemple. un currentImage dans une galerie où il y a de multiples galerie instances)? Les stocker sur le $scope objet qui appartient à cette galerie.

$champ d'application est automatiquement disponible pour vous dans la bonne partie du modèle.

Angulaire modèles sont minces

Venant d'un des Rails de fond sur lequel nous insistons sur les modèles de matières grasses et maigres contrôleurs, j'ai trouvé Angulaire "à peine là" modèles de surprenant. En fait, en mettant beaucoup de logique métier de votre modèle conduit souvent à des problèmes sur la ligne, comme on le voit parfois avec le modèle d'Utilisateur sur des Rails qui, si vous ne faites pas attention, va croître jusqu'à ce qu'elle devient difficile à maintenir.

Angulaire modèle est tout simplement un objet JavaScript ou primitif.

Tout objet peut être un modèle. Les modèles sont généralement définis à l'aide de JSON dans le contrôleur, ou AJAXed à partir d'un serveur. Un modèle peut-être un objet JSON, ou peut-être juste un string, array, ou même un certain nombre.

Bien sûr, il n'y a rien pour vous empêcher de vous ajouter des fonctions supplémentaires à votre modèle et de les stocker dans l'objet JSON si vous voulez, mais ce serait le portage dans un paradigme qui n'a pas vraiment d'ajustement Angulaire.

Angulaire objets sont généralement des banques de données, des fonctions pas.

Le modèle sur la face avant n'est pas le vrai modèle

Bien entendu, le modèle que vous détenez sur le client n'est pas le véritable modèle. Votre modèle, votre source unique de la vérité, la vie sur le serveur. Nous synchroniser à l'aide d'une API, mais si il y a un conflit entre les deux le modèle de votre base de données est évidemment la victoire finale.

Cela vous donne la vie privée pour des choses comme des codes de réduction, etc. Le modèle que vous trouverez sur votre front-end est un synchronisée version du public propriétés du modèle réel, qui est distant.

La logique métier peut vivre dans les services.

Dites que vous voulez écrire une méthode pour faire quelque chose pour votre modèle, le synchroniser ou le valider par exemple. Dans d'autres cadres que vous pourriez être tenté de prolonger votre modèle avec une méthode pour ce faire. Dans Angulaire vous seriez plus susceptibles d'écrire un service.

Les Services sont les objets singleton. Comme n'importe quel autre objet JavaScript, vous pouvez mettre des fonctions ou des données. Angulaire est livré avec un tas de construit dans les services, tels que $http. Vous pouvez construire votre propre, et utiliser l'injection de dépendance pour fournir automatiquement à vos contrôleurs.

Un service peut contenir des méthodes de parler à une API RESTful par exemple, ou de valider vos données, ou de tout autre travail que vous pourriez avoir à faire.

Les Services ne sont pas des modèles

Bien sûr, vous ne devriez pas utiliser des services comme des modèles. Les utiliser comme des objets qui peuvent faire des trucs. Parfois ils font des trucs à votre modèle. C'est une façon différente de penser, mais réalisable.

7voto

Pablo De Nadai Points 897

J'ai créé cet exemple pour montrer comment extraire, stocker et partager des données entre les différents contrôleurs sans perdre son peut être liée à la fonctionnalité.

Live Exemple: http://pablodenadai.github.io/SharingModelsAngularJS/

Source code 1: (Ressources et le Modèle d'abstraction) https://github.com/pablodenadai/SharingModelsAngularJS/blob/master/app/scripts/controllers/main.js

Repo: https://github.com/pablodenadai/SharingModelsAngularJS

Espérons que cela aide.

7voto

marcoseu Points 2230

Tout d'abord, n'oublions pas que c'Angulaire est un site web sur cadre et si vous "gardez votre état" uniquement dans un objet, il ne survivront pas à l'utilisateur de frapper d'actualisation sur leur navigateur. Par conséquent, à comprendre comment maintenir l'état de Modèle de données dans une application basée sur le web signifie essayer de comprendre comment vous allez persister pour que votre code de la fonction dans un environnement de navigateur.

Angulaire, il est vraiment facile pour vous de persister votre état à l'aide de:

  1. Un appel à un Réparateur $ressource
  2. Une URL qui représente une instance de votre modèle

Dans votre exemple simple, le stockage de l'utilisateur des actions telles que l' selectedGallery et selectedPhoto peut être représenté à l'aide de l'URL avec quelque chose comme:

// List of galleries
.../gallery

// List of photos in a gallery
.../gallery/23

// A specific photo
.../gallery/23/photo/2

L'URL est essentielle, car elle permettra à l'utilisateur de naviguer dans l'historique du navigateur à l'aide de back et forward boutons. Si vous souhaitez partager cet état à l'autre partie de votre application web, application de fournir la richesse de méthodes pour vous de réaliser que l'utilisation de cookie/localStorage, caché cadre/des champs ou même de le stocker dans votre serveur.

Une fois que vous avez défini votre stratégie sur la façon de persister état différent de l'état de votre demande, il devrait être plus facile de décider si vous souhaitez accéder à ces persisté info à l'aide d'un objet singleton, comme prévu par .service ou une instance via .factory.

1voto

djsmith Points 1315

Angulaire de ne pas avoir une opinion sur la façon dont vous stockez ce que vous appelez "les objets de modèle". L'angle de contrôleur $scope existe uniquement comme un "modèle de vue" pour des fins de gestion de votre INTERFACE utilisateur. Je suggère de séparer ces deux notions dans votre code.

Si vous souhaitez que le concept de portée Angulaire notification de changement ($watch), vous pouvez utiliser un objet de l'étendue de stocker les données de votre modèle si vous le souhaitez (var myScope = $rootScope.$new()). Il suffit de ne pas utiliser le même objet de l'étendue à laquelle votre INTERFACE utilisateur est lié.

Je recommande l'écriture de services personnalisés à cette fin. De sorte que le flux de données va comme ceci:

AJAX --> Service Personnalisé --> Modèle d'Objet de l'Étendue --> Contrôleur --> UI Objet de l'Étendue --> DOM

Ou ceci:

AJAX --> Services Personnalisés --> Plaine de vieux Objets JavaScript --> Contrôleur --> UI Objet de l'Étendue --> DOM

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X