简体   繁体   中英

Saving only changed attributes in Backbone.js

I'm attempting to save only changed attributes of my model by doing the following:

        this.model.set("likes", this.model.get("likes") + 1);
        this.model.save();

and extending the Backbone prototype like so:

var backbone_common_extension = {
    sync: function(method,model,options) {
        options.contentType = 'application/json';
        if (method == 'update') {
            options.data = JSON.stringify(model.changedAttributes() || {});
        }
        console.log(options.data);
        Backbone.sync.call(this, method, model, options);
    }
};

_.extend(Backbone.Model.prototype, backbone_common_extension);

The problem is that model.changedAttributes() is always empty. I've tried passing {silent: true} on the set method, but same thing. How can I keep backbone from clearing out changedAttributes() before sync?

Relying on changedAttributes for this sort of thing tends not to work very well, Backbone doesn't really have a well defined set/commit/save/rollback system so you'll find that changedAttributes will get emptied when you don't expect it to.

Lucky for you, that doesn't matter; unlucky for you, it doesn't matter because your whole approach is wrong. What happens if you load your model from the server and then five likes come in from other browsers? Your approach would overwrite all those likes and data would get lost.

You should let the server manage the total number of likes and your model should simple send a little "there is one more like" message and let the server respond with the new total. I'd do it more like this:

// On the appropriate model...
add_like: function() {
    var _this = this;
    $.ajax({
        type: 'post',
        url: '/some/url/that/increments/the/likes',
        success: function(data) {
            _this.set('likes', data.likes);
        },
        error: function() {
            // Whatever you need...
        }
    });
}

Then the /some/url/... handler on the server would send a simple "add one" update to its database and send back the updated number of likes. That leaves the database responsible for managing the data and concurrency issues; databases are good at this sort of thing, client-side JavaScript not so much.

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