I'm a little confused as to why my event is not firing on a child view. I usually set a $el
attribute but in this instance I am reusing the child view multiple times so I'm setting the className
attribute but it's still not firing.
Here's my code:
Child view (simplified):
var LogbookEntryView = Backbone.View.extend({
className: 'log-entry',
collection: Logbook,
template: _.template($('#logbook-entry-view').html()),
events: {
"click .edit-log": "editLog",
"click .popup": "modalHandler"
},
render: function(model) {
return this.template(model);
},
editLog: function(event) {
var target = $(event.currentTarget);
var id = $(target).data('id');
var url = target.attr("href");
var modal = $(target).data('modal');
this.loadModal(modal, url);
return false;
}
})
Parent view method:
displaySkillsByCat: function() {
var entryView = new LogbookEntryView();
_.each(_.keys(app.data), function(cat) {
$("#logbook-tabs ." + cat).removeClass('disabled');
$("#" + cat).append(app.template);
_.each(app.data[cat], function(item) {
$("#" + cat + " .logbook-list").append(entryView.render(item.attributes));
});
})
return this;
},
groupSkillsByCategory: function(){
var cats = _.uniq( this.collection.pluck('cat_group') );
_.each(cats, function(cat, index){
app.data['cat' + cat] = Logbook.where({'cat_group': cat});
});
},
The problem is that you say you're reusing a view, but in practice, you're not using it at all.
You're just passing data through the render
function which returns a string, without any events or anything related to Backbone.
So the first step is to fix the child view class.
collection
property on a view isn't meant to be used that way, so remove that. el
or $el
(jQuery equivalent) with a template. render
should return this
as a standard. var LogbookEntryView = Backbone.View.extend({
className: 'log-entry',
template: _.template($('#logbook-entry-view').html()),
events: {
"click .edit-log": "editLog",
"click .popup": "modalHandler"
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
editLog: function(event) {
var $target = $(event.currentTarget);
var id = event.currentTarget.id;
var url = $target.attr("href");
var modal = $target.data('modal');
this.loadModal(modal, url);
return false;
},
modalHandler: function() {},
loadModal: function() {}
});
Then, in the parent view, you could simplify it a bit.
_.each
directly, you do not need _.keys
. If it's a Backbone collection, you could use app.data.each(...)
. el
DOMElement. displaySkillsByCat: function() {
var entryView = new LogbookEntryView();
_.each(app.data, function(entries, cat) {
$("#logbook-tabs ." + cat).removeClass('disabled');
$("#" + cat).append(app.template);
// select this element once instead of each iteration
var $list = $("#" + cat + " .logbook-list");
_.each(entries, function(item) {
// here, use `.el` to get the sub-view's element
$list.append(new LogbookEntryView({ model: item }).render().el);
});
})
return this;
},
The above is a simple fix for your situation, but if you don't keep track of the sub views and they are listening to a Backbone model, there could be memory leaks.
Here's a more efficient way to render a list with Backbone .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.