J'ai le même problème lorsque j'écris mon application Backbone. Devoir gérer des modèles embarqués / imbriqués. J'ai fait quelques ajustements que je pensais être une solution assez élégante.
Oui, vous pouvez modifier la méthode d'analyse pour changer un attribut autour de l'objet, mais tout cela est en fait un code IMO assez impossible à maintenir, et ressemble plus à un hack qu'à une solution.
Voici ce que je suggère pour votre exemple:
Définissez d'abord votre modèle de mise en page comme tel.
var layoutModel = Backbone.Model.extend({});
Alors voici votre modèle d'image:
var imageModel = Backbone.Model.extend({
model: {
layout: layoutModel,
},
parse: function(response){
for(var key in this.model)
{
var embeddedClass = this.model[key];
var embeddedData = response[key];
response[key] = new embeddedClass(embeddedData, {parse:true});
}
return response;
}
});
Notez que je n'ai pas altéré le modèle lui-même, mais simplement renvoyer l'objet souhaité à partir de la méthode d'analyse.
Cela devrait garantir la structure du modèle imbriqué lorsque vous lisez à partir du serveur. Maintenant, vous remarquerez que l'enregistrement ou la configuration n'est en fait pas gérée ici car je pense qu'il est logique que vous définissiez explicitement le modèle imbriqué en utilisant le modèle approprié.
Ainsi:
image.set({layout : new Layout({x: 100, y: 100})})
Notez également que vous invoquez en fait la méthode d'analyse dans votre modèle imbriqué en appelant:
new embeddedClass(embeddedData, {parse:true});
Vous pouvez définir autant de modèles imbriqués dans le model
champ que nécessaire.
Bien sûr, si vous souhaitez aller jusqu'à enregistrer le modèle imbriqué dans sa propre table. Ce ne serait pas suffisant. Mais dans le cas de la lecture et de la sauvegarde de l'objet dans son ensemble, cette solution devrait suffire.
define(['modelFile'], function(MyModel){... do something with MyModel})
Mais vous avez raison. Je prends l'habitude de faire référence au modèle par la convention que vous avez suggérée.Backbone.Model.prototype.parse
fonction. Ensuite, tout ce que vos modèles ont à faire est de définir les types d'objet du sous-modèle (dans votre attribut "modèle").Je poste ce code comme exemple de la suggestion de Peter Lyon de redéfinir l'analyse. J'ai eu la même question et cela a fonctionné pour moi (avec un backend Rails). Ce code est écrit en Coffeescript. J'ai rendu certaines choses explicites pour les personnes qui ne le connaissent pas.
ou, en JS
la source
Utilisation à
Backbone.AssociatedModel
partir d' associations de dorsales :la source
Je ne suis pas sûr que Backbone lui-même ait un moyen recommandé de le faire. L'objet Layout a-t-il son propre ID et son propre enregistrement dans la base de données principale? Si c'est le cas, vous pouvez en faire son propre modèle comme vous l'avez fait. Sinon, vous pouvez simplement le laisser en tant que document imbriqué, assurez-vous simplement de le convertir correctement depuis et vers JSON dans les méthodes
save
etparse
. Si vous finissez par adopter une approche comme celle-ci, je pense que votre exemple A est plus cohérent avec le backbone car ilset
sera correctement mis à jourattributes
, mais encore une fois, je ne suis pas sûr de ce que fait Backbone avec les modèles imbriqués par défaut. Il est probable que vous aurez besoin d'un code personnalisé pour gérer cela.la source
new
opérateur. Je l'ai modifié pour corriger cette erreur.J'irais avec l'option B si vous voulez garder les choses simples.
Une autre bonne option serait d'utiliser Backbone-Relational . Vous définiriez simplement quelque chose comme:
la source
J'utilise le plugin Backbone DeepModel pour les modèles et attributs imbriqués.
https://github.com/powmedia/backbone-deep-model
Vous pouvez créer une liaison pour modifier les niveaux d'événements en profondeur. par exemple:
model.on('change:example.nestedmodel.attribute', this.myFunction);
la source
Version CoffeeScript de la belle réponse de rycfung :
N'est-ce pas doux? ;)
la source
J'ai eu le même problème et j'ai expérimenté le code de la réponse de rycfung , ce qui est une excellente suggestion.
Si, cependant, vous ne voulez pas
set
directement les modèles imbriqués, ou ne voulez pas passer constamment{parse: true}
dans leoptions
, une autre approche serait de se redéfinirset
.Dans Backbone 1.0.0 ,
set
est appeléconstructor
,unset
,clear
,fetch
etsave
.Considérez le super modèle suivant , pour tous les modèles qui doivent imbriquer des modèles et / ou des collections.
Notez que
model
,_setModel
et_unsetModel
sont laissés en blanc exprès. À ce niveau d'abstraction, vous ne pouvez probablement pas définir d'actions raisonnables pour les rappels. Cependant, vous souhaiterez peut-être les remplacer dans les sous-modèles qui s'étendentCompoundModel
.Ces rappels sont utiles, par exemple, pour lier des écouteurs et propager des
change
événements.Exemple:
Avec cela, vous avez la création automatique de modèles imbriqués et la propagation d'événements. Un exemple d'utilisation est également fourni et testé:
Production:
la source
Je me rends compte que je suis en retard à cette soirée, mais nous avons récemment publié un plugin pour gérer exactement ce scénario. Cela s'appelle backbone-nestify .
Ainsi, votre modèle imbriqué reste inchangé:
var Layout = Backbone.Model.extend({...});
Utilisez ensuite le plugin lors de la définition du modèle conteneur (en utilisant Underscore.extend ):
Après cela, en supposant que vous avez un modèle
m
qui est une instance deImage
, et que vous avez défini le JSON à partir de la questionm
, vous pouvez faire:la source
Utiliser des formes de base
Il prend en charge les formulaires imbriqués, les modèles et toJSON. TOUT EMBRIQUÉ
la source
Si vous ne souhaitez pas ajouter encore un autre framework, vous pouvez envisager de créer une classe de base avec substitué
set
ettoJSON
et l'utiliser comme ceci:Vous aurez besoin
BaseModel
de cette réponse (disponible, si vous le souhaitez, comme une base ).la source
Nous avons également ce problème et un collaborateur a implémenté un plugin nommé backbone-nested-attributes.
L'utilisation est très simple. Exemple:
Avec cela, le modèle Tree peut accéder aux fruits:
Vous pouvez voir plus d'informations ici:
https://github.com/dtmtec/backbone-nested-attributes
la source