简体   繁体   中英

Backbone.js: smart update of a list of changed attributes

I know this problem have been discussed several times, but I could not find an answer to one of its many aspects, that I'll try to explain here.

Model save() keeps sync between client and server. Backbone.js pushes you to use it in one of these 2 ways (afaik):

  1. Save all the items of a model: this will send everything to the server, even attributes used only on the client side and attributes that have not been changed. This is the default for new models (when model.isNew() returns true ).
  2. Save with patch:true will only send changed attributes of the model to the server. In Backbone, it means that ONLY the attributes returned by changedAttributes() will be sent.

The point is that changedAttributes() ONLY returns the changes since the LAST change event. This is useful for models that are not updating all the time, and actually can afford to automatically make an ajax request on any change.

But if you have a model that is constantly changing (for example a code/text editor or an element that can be dragged/dropped and its position should be tracked), you cannot just save at every single change event. You need to save at time intervals, ALL the changed attributes since the last time you called save() .

Do you think Backbone.js actually provides a good support for this kind of synchronization? Does Bakcbone.js track changes since last save() (and not only since last change event)? Or you have to do it "manyally"?

You'll have to extend backbone models with your own base model.

var BaseModel = Backbone.Model.extend({
    save: function(key, val, options){
        var attrs
        if (key == null || typeof key === 'object') {
          attrs = key;
          options = val;
        } else {
           (attrs = {})[key] = val;
        }  
        attrs = _.extend(this.unsaved || {}, attrs);
        this.unsaved = {};
        return Backbone.Model.prototype.save.call(this, attrs, options);
    },
    set: function(key, val, options) {
       var attr
       if (key == null) return this;
       if (typeof key === 'object') {
          attrs = key;
          options = val;
       } else {
         (attrs = {})[key] = val;
       }
       this.unsaved = _.extend(this.unsaved || {}, attrs);
       return Backbone.Model.prototype.save.call(this, attrs, options);
    }
});

Totally untested code, but should be very close to what you need to do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM