It's my first post here so please be nice ;) I'm trying to create a Backbone+requireJS sample app and I have stumbled upon a strange problem. In my views initialize function I bind to models change event by
this.model.on("change", this.change());
Event is triggered correctly when data is loaded and all is fine. In my view I also bind to a click event. On click I try to change one of the properties and I was hoping for a change event, but it never came.
I was trying some stuff recommended here on stackoverflow (here, here, and there) but with no luck.
In my guts I feel it has to do with event binding. When I tried to bind again to models on change event inside click callback it started to work. So now I sit here and I'm, hm, confused. Could someone shed some light on this issue?
My View:
define(
[
'jquery',
'underscore',
'backbone',
'text!templates/news/newsListItem.html'
],
function($, _, Backbone, newsListItemTemplate)
{
var NewsListItemViewModel = Backbone.View.extend({
tagName: 'li',
events: {
"click a" : "onLinkClick"
},
initialize: function(){
this.model.on("change", this.changed());
},
render: function()
{
this.$el.html(_.template(newsListItemTemplate, this.model.toJSON()));
},
changed: function()
{
this.render();
console.log("changed");
},
//GUI functions
onLinkClick: function(e)
{
console.log("click!");
this.model.toggle();
this.model.on("change", this.changed());
}
});
var init = function(config){
return new NewsListItemViewModel(config);
}
return {
init : init
}
}
);
My Model:
define(
['jquery', 'underscore', 'backbone'],
function($, _, Backbone){
var NewsListItemModel = Backbone.Model.extend({
toggle: function() {
this.set('done', !this.get('done'));
this.trigger('change', this);
}
});
var init = function(data)
{
return new NewsListItemModel(data);
}
return {
init: init,
getClass: NewsListItemModel
};
}
);
Thanks for any input :)
First, you should use a function as event handler - not its result. Hence, change the line into this:
this.model.on("change", this.changed.bind(this));
As it stands now, you actually fire this.changed()
function just once - and assign its result (which is undefined
, as the function doesn't have return
statement) to be the model's change
event handler.
Second, you shouldn't rebind this handler in onLinkClick
: once bound, it'll stay here. It looks like it's more appropriate to trigger
this event instead:
onLinkClick: function(e)
{
console.log("click!");
this.$el.toggle();
this.model.trigger('change');
}