While TJ has the right answer, I have a better way to achieve what he suggest.
Instead of making a raw clone of the attributes, I prefer to keep a master copy of the model at the start of the app or the initialize of the view.
this.master = this.model.clone();
// ... then changes are made to this.model
When ready to save, use the master model to compare the attributes and retrieve the changes directly.
var changes = this.master.changedAttributes(this.model.attributes);
if (changes !== false) this.model.save(changes, { patch: true });
With this, you can skip the dataTosend = model.pick(_.keys(changedAttrs))
altogether since changes
already is an object of all the differences with the initial state of the master model.
If it's a view that is re-used after the model save:
var View = Backbone.View.extend({
initialize: function() {
this.updateMaster();
},
saveChanges: function() {
var changes = this.master.changedAttributes(this.model.attributes);
if (changes !== false) {
this.model.save(changes, {
patch: true,
context: true,
success: this.updateMaster
});
}
},
updateMaster: function() {
this.master = this.model.clone();
},
});