AJP
AJP

Reputation: 28453

Sequential Backbone model.set overwrites model.changed attribute

I'm sure I'm misunderstanding something about the purpose of the backbone models' changed, changedAttributes and set attribute/methods. When I call set twice on a model, only the second attributes are included in the changed attribute. e.g:

model.set('field1', 'some diff value', {silent: true});
model.changed;   // => {'field1': 'some diff value'}

model.set('field2', 'some other value', {silent: true});
model.changed;   // => {'field2': 'some other value'}

What I'm expecting from the second access of changed is {'field1': 'some diff value', 'field2': 'some other value'}

I want the full list of changed values so I can optimise a sync to the server that would otherwise potentially drag in many other, large, unmodified fields. I'm doing it currently with my own version of changed that is only equal to {} once the model has been saved to the server.

What am I missing / misunderstanding about Backbone?

Upvotes: 1

Views: 105

Answers (2)

jurassix
jurassix

Reputation: 1509

from the docs:

The changed property is the internal hash containing all the attributes that have changed since the last set. Please do not update changed directly since its state is internally maintained by set. A copy of changed can be acquired from changedAttributes.

Looking at the annotated source it looks like the only way to do what your after is to call save on the model passing in all the changed fields and the option patch: true

model.save({'field1': 'some diff value', 'field2': 'some other value'}, {patch: true})

another option could be to listen to all change events on the model and mange an internal change map; be sure to flush this map when you update server side.

Upvotes: 1

maxbeatty
maxbeatty

Reputation: 9325

I want the full list of changed values so I can optimise a sync to the server that would otherwise potentially drag in many other, large, unmodified fields

Assuming you're using version 0.9.9+, you could pass in the patch option to your save call which will only send the changed attributes to the server. See Model save docs

model.set('field1', 'some diff value', {silent: true});
model.set('field2', 'some other value', {silent: true});
model.save({patch: true}); // field1 and field2 are only attributes saved to server

Upvotes: 1

Related Questions