2012-04-03 5 views
1

J'aimerais pouvoir appeler save() sur un modèle de backbone et que le backend retourne toute la collection de ce modèle au lieu des attributs modifiés du modèle. J'aimerai alors que le backbone mette à jour toute la collection retournée. Le cas d'utilisation pour ceci est le suivant:Sauvegarder Backbone.js Modéliser et mettre à jour la collection entière

Un utilisateur a plusieurs adresses et peut choisir une adresse de livraison de cette collection. Si elle choisit une adresse de livraison différente de la collection, l'adresse de livraison précédente doit être mise à jour à l'état «juste une autre adresse ordinaire». Pour cela, toute la collection doit être mise à jour au lieu du seul modèle modifié.

Est-ce que c'est en quelque sorte possible dans backbone.js?

Merci beaucoup d'avance!

Répondre

4

les modèles liés à des collections contiennent leur parent de collection en tant que propriété. De plus, puisque vous renvoyez une liste de modèles, nous pouvons supposer qu'elle figure toujours dans une liste.

mymodel = Backbone.Model.extend({ 
    parse: function (data) { 
    if(this.collection && typeof(data) === 'array') { 
     this.collection.reset(data); 
    } 
    return data; 
    } 
}); 
+0

bien oui, merci - cela fait exactement ce que je voulais. – Hendrik

+1

"typeof (data) === 'array'" devrait être "_.isArray (data)" à la place, btw. – Hendrik

1

Oui, c'est possible. Vous aurez besoin de passer outre la fonction sync sur le modèle

MyModel = Backbone.Model.extend({ 
    sync: function(method, model) { 
    if (method === 'create') { 
     //perform save logic and update the model's collection 
    } else if (method === 'update') { 
     //perform save logic and update the model's collection 
    } else if (method === 'read') { 
     ... 
    } else if (method === 'destroy') { 
     ... 
    } 
    } 
}); 

Jetez un oeil à la fonction Backbone.sync pour plus d'informations.

+0

Je suppose que PRÉPONDÉRANTS synchronisation ne contribue pas trop pour ce cas d'utilisation car il ne concerne pas la réponse à revenir du serveur (qui est la tâche de la méthode de rappel de succès) – Hendrik

0

Ce que votre cas d'utilisation appelle réellement est la mise à jour de deux modèles, pas la mise à jour d'une collection entière. (En dehors de la récupération, les collections n'interagissent pas avec le serveur dans Backbone.) En supposant que vous avez les adresses A, B et C, A comme adresse de livraison actuelle et C comme nouvelle adresse de livraison, votre code peut simplement:

  1. Mettre à jour C soit la nouvelle adresse de livraison.
  2. Mettre à jour A pour être juste une autre adresse.

Si votre problème est que vous ne savez quelle adresse est l'adresse actuelle (c.-à-adresse A), alors vous pouvez simplement rechercher dans votre collection pour elle (par exemple, « donnez-moi l'expédition actuelle adresse "), mettez à jour C, puis mettez à jour l'adresse renvoyée (adresse A).

Si vous absolument besoin de mettre à jour une collection entière (vous n'avez pas), passer en revue collection.models et mettre à jour chacun individuellement. Il n'y a tout simplement pas de concept dans Backbone d'une collection agissant sur RESTfully.

Modifier: J'ai peut-être mal interprété votre question. Si vous vouliez mettre à jour la collection sur le client (c'est-à-dire que vous n'aviez pas l'intention de mettre à jour la collection sur le serveur), le code est toujours similaire, vous mettez juste à jour l'ancien et le nouveau.

+0

oui je voulait vraiment dire mettre à jour la collection sur le client et c'est aussi le problème avec l'approche ci-dessus parce que si je mettais simplement C et A à leur nouvel état sur le client leur état serait désynchronisé avec le serveur s'il ne pouvait pas être sauvegardé sur le serveur avec succès. – Hendrik

2

Je ne pense pas que la priorité soit de synchroniser ou de casser les attentes en matière de retours.

Il serait plus simple que je suppose de passer outre save sur le modèle, quelque chose sur les lignes de:

save: function (key, value, options) { 
    var p = Model.prototype.save.call(this, key, value, options), 
     self=this; 
    if (this.collection) { 
     p.done(function() { self.collection.fetch(); }); 
    } 
    return p; 
} 

qui permettra d'économiser en utilisant la save normale obtenir sa promesse, et si l'épargne a réussi et le modèle fait partie d'une collection, il va chercher la collection sur le serveur.

Une autre façon serait de se lier à l'événement change du modèle, vérifier s'il appartient à une collection et récupérer, mais cela se produirait également sur set.

+0

Je ne l'ai pas essayé mais je suppose que cela fonctionnerait réellement avec le petit inconvénient d'un cycle de demande supplémentaire. – Hendrik

+0

@Hendrik Où voyez-vous le cycle supplémentaire? – ggozad

+0

Eh bien, si je ne manque rien ici le modèle est sauvé d'abord et si cela a été un succès alors le client récupère la collection. Si au lieu de cela le serveur renvoie juste la collection directement une fois que le modèle a été stocké avec succès, toute l'opération nécessite une requête de moins. Ai-je tort? – Hendrik

Questions connexes