Question

Dites que j'ai une collection et que j'ai apporté des modifications à bon nombre de ses modèles. Quelle est la meilleure façon de sauver toutes les modifications en utilisant une seule demande HTTP?

Était-ce utile?

La solution

Habituellement, les backends gèrent la création / mise à jour d'instance unique. Vous devez changer cela pour accepter un tableau d'objets.

Cela dit, du côté client, vous devez aller directement à la fonction d'épine dorsale.Sync

Backbone.sync = function(method, model, options)

Dans ce cas, votre modèle devrait être un tableau de modèle. La méthode doit être "Créer" ou "Enregistrer" et les options prennent le même type d'options qu'un appel jQuery Ajax (erreur, succès, etc.)

Autres conseils

Je vais faire la mauvaise chose ici et citer Wikipedia concernant Pratiques reposantes appropriées: un METTRE à example.com/resources devrait remplacer toute la collection par une autre collection. Sur cette base, lorsque nous avons dû prendre en charge l'édition de plusieurs éléments simultanément, nous avons rédigé ce contrat.

  1. Le client envoie {"resources": [{resource1},{resource2}]}
  2. Le serveur remplace l'intégralité de la collection par les nouvelles informations du client et renvoie les informations après avoir été persistée: {"resources": [{"id":1,...},{"id":2,...}]}

Nous avons écrit la moitié du serveur du contrat en rails, mais voici la moitié du client (dans CoffeeScript, désolé!):

class ChildElementCollection extends Backbone.Collection
  initialize: ->
    @bind 'add', (model) -> model.set('parent_id', @parent.id)

  url: -> "#{@parent.url()}/resources" # let's say that @parent.url() == '/parent/1'
  save: ->
    response = Backbone.sync('update', @, url: @url(), contentType: 'application/json', data: JSON.stringify(children: @toJSON()))
    response.done (models) => @reset models.resources

Je pensais que c'était un parcelle Plus facile à implémenter que l'emportant sur la saillie.Sync. Un commentaire sur le code, nos collections étaient toujours des objets enfants, ce qui devrait expliquer pourquoi le code définit un "parent_id" chaque fois qu'un objet est ajouté à la collection et comment la racine de l'URL est l'URL du parent. Si vous avez des collections au niveau de la racine que vous souhaitez modifier, alors supprimez simplement le @parent Entreprise.

Tu devrais prolonger Backbone.Collection, lui donnant un save() Méthode qui vérifierait chacun de ses modèles hasChanged().

Alors ça devrait appeler Backbone.sync, que vous devrez probablement s'étendre un peu dans une fonction de synchronisation personnalisée. Si vous utilisez une coutume Backbone.sync Fonction, alors assurez-vous de le définir sur votre collection.

var CollectionSync = function(method, model, [options]) {
    // do similar things to Backbone.sync
}

var MyCollection = Backbone.Collection.extend({
    sync: CollectionSync,
    model: MyModel,
    getChanged: function() {
        // return a list of models that have changed by checking hasChanged()
    },
    save: function(attributes, options) {
        // do similar things as Model.save
    }
});

Une approche différente (en utilisant un modèle pour représenter la collection) est ici: "Comment" pour sauver une collection entière dans Backbone.js - Backbone.Sync ou jQuery.ajax?

J'aime aussi https://stackoverflow.com/a/7986982/137067

Ce code ajoute une nouvelle méthode au prototype de collection juste pour appeler la méthode de sauvegarde des modèles qui avaient changé. Cela a fonctionné pour moi:

Backbone.Collection.prototype.saveAll = function(options) {
 return $.when.apply($, _.map(this.models, function(m) {
   return m.hasChanged() ? m.save(null, options).then(_.identity) : m;
 }));
};

Lien gist: https://gist.github.com/juanitor/701c67279bac1529b88

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top