Given the following snippet:
var m = new Backbone.Model({
name: 'joshua'
});
m.set('name', 'something else');
If I now call m.hasChanged()
or m.hasChanged('name')
I get false
. Why? My understanding is that both of these should return true
.
m.changedAttributes()
also returns false.
Here is a fiddle that illustrates what I'm doing, and expecting: /
EDIT: It seems that unless you pass { silent: true; }
to the set()
method then it will fire the change
event on your model which clears out the changedAttributes()
, etc. Essentially these properties only track changes since the last time the change
event was triggered.
I read that in the documentation but didn't really understand it at first.
This doesn't seem very useful to me. I would appreciate any explanation of why this works the way it does and the best way to achieve the result I want. (Passing around {silent: true; }
and giving up usage of the change
event seems like a waste.)
Given the following snippet:
var m = new Backbone.Model({
name: 'joshua'
});
m.set('name', 'something else');
If I now call m.hasChanged()
or m.hasChanged('name')
I get false
. Why? My understanding is that both of these should return true
.
m.changedAttributes()
also returns false.
Here is a fiddle that illustrates what I'm doing, and expecting: http://jsfiddle.net/9cvVv/88/
EDIT: It seems that unless you pass { silent: true; }
to the set()
method then it will fire the change
event on your model which clears out the changedAttributes()
, etc. Essentially these properties only track changes since the last time the change
event was triggered.
I read that in the documentation but didn't really understand it at first.
This doesn't seem very useful to me. I would appreciate any explanation of why this works the way it does and the best way to achieve the result I want. (Passing around {silent: true; }
and giving up usage of the change
event seems like a waste.)
3 Answers
Reset to default 15Unless you pass { silent: true; }
to the set()
method then it will fire the change
event on your model which clears out the changedAttributes()
, etc. Essentially these properties only track changes since the last time the change
event was triggered.
So the answer is to call this instead:
m.set('name', 'something else', {silent: true})
This post is premised on the previous behavior of older versions of Backbone. hasChanged
does now (as of 0.9.10) always returns true
after set(..)
is called. The silent
flag no longer has any effect.
This is confusingly masked in the jsfiddle linked in the question which uses a CDN-hosted copy of backbone.js which always uses the latest version. Here's some updated jsfiddles showing the change in behavior:
- jsfiddle using Backbone 0.9.2
- jsfiddle using Backbone 0.9.10
Model.set()
takes an attributes hash as the first argument. Try m.set({'name': 'something else'});
. Doing m.set('name', 'something')
doesn't set 'name', so it never triggers the change
event and your call to hasChanged()
returns false
. You can always inspect the current value of the attributes hash by logging out m.attributes
- though accessing and manipulating it directly isn't recommended as none of the change events will fire that way.