In backbone.js, I'm noticing that the change
and all
events on a Model
do not fire if you set
the Model's attributes to its existing attributes.
For example, if I set up the following events:
ActiveUser.bind('change', this.displayActiveUser, this);
ActiveUser.bind('all', this.displayActiveUserAll, this);
And then I manually set the value of ActiveUser to the empty string:
ActiveUser.set({ text : '' });
The events fire if and only if ActiveUser.text
is not already set to the empty string.
This is reasonable behaviour. However, is there an event I can use that will fire even if the value being set is the existing value?
Update: I don't see anything in the official Backbone.js list of events. Hmm.
In backbone.js, I'm noticing that the change
and all
events on a Model
do not fire if you set
the Model's attributes to its existing attributes.
For example, if I set up the following events:
ActiveUser.bind('change', this.displayActiveUser, this);
ActiveUser.bind('all', this.displayActiveUserAll, this);
And then I manually set the value of ActiveUser to the empty string:
ActiveUser.set({ text : '' });
The events fire if and only if ActiveUser.text
is not already set to the empty string.
This is reasonable behaviour. However, is there an event I can use that will fire even if the value being set is the existing value?
Update: I don't see anything in the official Backbone.js list of events. Hmm.
Share Improve this question edited Mar 27, 2012 at 16:14 Richard asked Mar 27, 2012 at 16:03 RichardRichard 32.9k30 gold badges111 silver badges146 bronze badges 3-
2
You can always manually run
ActiveUser.trigger('change')
– abraham Commented Mar 27, 2012 at 16:13 - Thanks - that's what I'll do! – Richard Commented Mar 27, 2012 at 16:19
- I added my ment as an answer. – abraham Commented Mar 27, 2012 at 16:35
3 Answers
Reset to default 8You can always trigger the change event manually with ActiveUser.trigger('change');
.
Trigger change event manually as abraham said
MyModel.trigger('change')
So its possible to trigger change event manually but it will not work well in some cases. Consider the case when your render method takes properties from model and your model is empty initially, so if your code sets something on model and straight after that line you say MyView.render()
or MyModel.trigger('change')
then what happens your render method might be faster and will not even take newly set properties.
Quick hacky alternative could be each time you set something, generate random number along and pass it to model:
MyModel.set({myProperty:something,rand:Math.random()});
or
MyModel.set({myProperty:something,t:(new Date).getTime()});
So in this case you are sure that model will always fire change event just because something changes, but it is hacky and if you have a lot going on then your app will bee random number calculator.
Alternatively go with Peter Lyons method.
Seems like you need a Backbone.Model subclass that is a parent class of any of your own Model classes that want this behavior. Override the set
method something along these lines. The logic to only fire events on changes is coded into Backbone.Model.set
in a way that doesn't easily support adding a new option.
(...excerpt...)
set: function(key, value, options) {
//Handle both "key", value and {key: value} -style arguments.
if (_.isObject(key) || key == null) {
options = value;
}
this.change(options); //This fires the event
Backbone.Model.prototype.set.apply(this, arguments);//Trigger normal behavior as well