I have a collection that I'm listening to all model change events on. In one specific model property, I need to set an additional value on the model, which causes the event to be fired again. I'm trying to pass in custom options so I can ignore the second call. I don't want to use { silent: true }
because I need the UI to update still.
The problem is my custom options are making it through. I have found the reason is because the change event is being fired within the change event on the current model, so it just continues it in the backbone code, and my custom options aren't being passed in.
This is what I'm doing. This is rough code for example purposes and not exact.
var View = Backbone.View.extend({
initialize: function(){
this.collection = new Backbone.Collection();
this.listenTo(this.collection, "change", this._modelChange);
},
_modelChange: function(model, options)
{
if(!_.has(model.changed, "IsSelected")){
model.set({ Selected: true }, { modelChanging: true });
}
// Do some other things...
}
});
What's happening here is that I need to subscribe to any change event that happens and do something when it does. There are 10+ properties so I don't want to list them all. If the property that changed isn't IsSelected
, the I need to set it to true
. This will cause the change
event to fire again, and the _modelChange
method will be called again. This is where I'm expecting my { modelChanging: true }
option to be available, but it isn't. I've found that this is happening because it's setting the value of the model during a change event, so backbone will fire the event itself, and backbone doesn't know about my options that I passed in.
This is one solution I've come up with, but I really don't like it.
setTimeout(function(){
model.set({ Selected: true }, { modelChanging: true });
}, 0);
This will run it asynchronously so it will no longer be a part of the same event. I really don't like this and it feels like a major hack.
How can I accomplish this without a setTimeout
?