34 votes

Backbone.js mise à jour partielle du modèle

Est-il possible d'envoyer uniquement les propriétés modifiées d'un modèle lors de l'enregistrement des modifications?

BTW, y at-il un groupe / liste de diffusion "officiel" Backbone.js pour poser ce genre de questions?

46voto

Julien Points 7456

Épine dorsale ne prend pas en charge cette sortie de la boîte, mais vous avez tous les outils pour le faire. Si vous regardez la colonne vertébrale.sync, vous verrez qu'il appelle la méthode toJSON sur votre modèle pour obtenir les données à envoyer. Maintenant, vous pourriez avoir à modifier cela, mais voici l'essentiel:

initialize: function(){
  this.dirtyAttributes = {}
},
set: function(attrs, options){
  Backbone.Model.prototype.set.call(this, attrs, options);
  _.extend(this.dirtyAttributes, attrs);
},
toJSON : function(){
  json = this.dirtyAttributes;
  this.dirtyAttributes = {};
  return json;
}

Si vous voulez une solution complète, vous devez appliquer la même logique à annuler, effacer, enregistrer, etc. Mais je suppose que vous obtenez comment faire cela. J'ai mis le reset de la sale des attributs dans la méthode toJSON fonction, mais il faut vraiment être dans le succès de rappel (lors de l'appel de l'enregistrer).

33voto

Andrew Hare Points 159332

Actuellement épine dorsale ne prend pas en charge l'envoi d'une partie du modèle pour le serveur. Il serait un ajout intéressant cependant.

Si vous parcourez la source , vous pouvez voir qu' Backbone.sync (la partie de l'épine dorsale qui est responsable de communiquer avec le magasin de données) est l'un des constituants les plus simples de la colonne vertébrale et encapsule simplement le support ajax en jQuery ou Zepto.


Mise à JOUR

départ épine dorsale de la version 0.9.10, partielle mise à jour du modèle est pris en charge nativement par

model.save(attrs, {patch: true})

6voto

Jay Kumar Points 594

UPDATE: à partir du backbone version 0.9.10, la mise à jour partielle est supportée de manière native via

 model.save(attrs, {patch: true})
 


Jusqu'au 0.9.9 Une approche sans éditer directement le fichier de bibliothèque backbone.js. Ajoutez simplement le code suivant dans le fichier js de l’application et chargez-le après le chargement de backbone.js.

 //override the Backbone.sync to send only the changed fields for update (PUT) request
var Original_BackboneSync = Backbone.sync;

Backbone.sync = function(method, model, options) {
    /* just handle the data picking logic for update method */
    if (!options.data && model && method == 'update') {
        options.contentType = 'application/json';
        options.data = JSON.stringify(model.changedAttributes() || {});
    }

    //invoke the original backbone sync method
    return Original_BackboneSync.apply(this, arguments);
};

//Tested in Backbone.js 0.9.1
 

2voto

Brendan Delumpa Points 938

J'ai essayé plusieurs techniques ont été proposées ici, mais en fin de compte, décidé de modifier la colonne vertébrale.Modèle et de la colonne vertébrale.synchroniser directement. Ce que je voulais était de fournir une méthode peu invasive pour fournir cette fonctionnalité qui ne nécessitent pas d'instruire les développeurs de mon équipe sur le remplacement de la dorsale méthodes; trop sujettes à l'erreur. Ma solution consiste à transmettre uniquement une option pour le modèle "enregistrer" de la méthode. Par exemple:

//Note that this could be from your view or anywhere you're invoking model.save
saveToModel : function() {
    this.model.save({
        field1 : field1Value,
        field2 : field2Value,
        field3 : field3Value
    }, {partialUpdate : true}
}

Maintenant, pour activer cette fonctionnalité, j'ai fait quelques très légères modifications pour la colonne vertébrale.De modèle.enregistrer et de la colonne vertébrale.la synchronisation. Ici est le changement de la colonne vertébrale.De modèle.enregistrer:

//If a partialUpdate is required, create a member on the options
//hash called updateAttrs and set it to attrs
if (options.partialUpdate != "undefined" && options.partialUpdate) {
    options.updateAttrs = attrs;
}
//--->>>Put the block above right above the return line
return (this.sync || Backbone.sync).call(this, method, this, options);

Ce qui se passe ici est que si partialUpdate est passé comme une option, puis un nouveau membre appelé updateAttrs est créé sur les options de hachage. Les options de hachage est automatiquement transmise à la colonne vertébrale.la synchronisation.

Pour La Colonne Vertébrale.sync, j'ai changé le conditionnel suivant:

// Ensure that we have the appropriate request data.
if (!params.data && model && (method == 'create' || method == 'update')) {
    params.contentType = 'application/json';
    params.data = JSON.stringify(model.toJSON());
}

pour...

// Ensure that we have the appropriate request data.
if (!params.data && model && (method == 'create' || method == 'update')) {
    params.contentType = 'application/json';

    //If doing a partial model update, then grab the updateAttrs member
    //from options. Will not interfere with line directly below as params.data
    //will have been set.
    params.data = (options.partialUpdate != "undefined" && options.partialUpdate)
                ? params.data = JSON.stringify(options.updateAttrs)
                : params.data = JSON.stringify(model.toJSON());
}

L'ajout de l'extra conditionnelle vérifie si partialUpdate a été fixée, si c'est cela, définissez les paramètres.les données d'options.updateAttrs. Ce sera ensuite transféré à l'Ajax de jquery méthode.

2voto

mateusmaso Points 1577

Au lieu de overrite Backbone.sync vous pourriez le faire à l' intérieur Model.sync méthode, et puisque vous accès cant model.changedAttributes() renvoient toujours faux dans cette méthode, il y a un changement d' attribut à l' intérieur options que vous pouvez obtenir ces valeurs et envoyer des données de demande à l'intérieur:

 sync: (method, model, options) ->
    if method is "update"
        options.contentType = 'application/json'
        changedData = {}
        for attr in _.keys(options.changes)
            changedData[attr] = model.get(attr)
        options.data = JSON.stringify changedData

    Backbone.sync method, model, options
 

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