Backbone click event not firing on dynamic view
Solution 1
There are some things that might be the cause of the problem.
First of all, your el
declaration seems to be suspect. If you want a div with that class you just have to define the className
attribute since the default for backbone views is div
.
Instead of: el: '<div class="vendor-video" />'
just use: className: 'vendor-video'
I don't see any details about your view initialization methods but the best practice is to initialize a view and then render it to the container:
var yourVideoDivView = new videoDivView({model: model});
$("#your-video-container").html(yourVideoDivView.render().el)
also to get the last line work you have to return this;
on your render method.
render: function(){
...
return this;
}
About using this.delegateEvents()
, you should call this function after your view is already in the DOM
otherwise it makes no sense. ie:
$("#your-video-container").html(yourVideoDivView.render().el)
yourVideoDivView.delegateEvents();
delegateEvents()
will makes your view events alive again.
Solution 2
Try a this.delegateEvents()
after you render the new content.
Solution 3
I had a similar problem.
You can resolve this problem in two steps.
- Create a tagName
in view
- Append your template in this.$el
That's all.
And it work without this.delegateEvents()
Drew Bartlett
Updated on July 23, 2022Comments
-
Drew Bartlett almost 2 years
I have a backbone view that creates a new div for each model that is passed into it. However, I cannot get any sort of events to fire (click a.change-status) on the view and I assume it's because the elements inside of it are also generated from a template. Please let me know if there's some way around this.
var videoDivView = Backbone.View.extend({ el: '<div class="vendor-video" />', initialize: function(){ _.bindAll(this); this.render(); this.model.on('change:published', this.enableSaveButton); }, events: { 'click a.change-status' : 'changeVideoStatus' }, template: video_tmpl, render: function(){ this.$el.attr("id", 'video-'+this.model.id); this.$el.html(this.template(this.model.toJSON())); this.$el.data('status', video_statuses[this.model.get('published')]); }, changeVideoStatus: function(e) { console.log(this.model); return false; }, enableSaveButton: function() { $('#save-changes').removeClass('disabled').removeAttr('disabled'); } });
an example template would look like:
<script id="single-video-tmpl" type="text/x-jquery-tmpl"> <div> <div class="video-info"> <span class="video-title"><%=video_title%></span> <div class="bottom-info"> <a href="#<%=id%>" class="change-status"></a> </div> </div> </div> </script>
-
Drew Bartlett over 10 yearsI tried adding that in and it didn't seem to change anything :(
-
Drew Bartlett over 10 yearsso if I run div.$el.find('a.change-status').trigger('click'); right after delegateEvents() it fires, but otherwise if I click it will not fire. Do you think it could have to do with that this is wrapped inside a couple other views? It's wrapped in a videoSet view that's then wrapped in a larger view. Would that effect this?
-
Drew Bartlett over 10 yearsnevermind, I had to render the parent view the same way as above, thanks!