Reputation: 8545
What's the best way of creating jQuery click events for a backbone view that is rendered multiple times? It seems like I should be using $().on() in my view's initializer, but this doesn't work unless I call it after it is rendered.
Basically, I'm rendering a table, and checking for click events on the rows. Here's what I'm trying (in coffeescript). This does not work -
class MyGridView extends Backbone.View
el: '#myGrid'
template: _.template(TableTmpl)
initialize: ->
# $('tr',@el).on 'click', -> console.log($(@).attr('model')) # WRONG
$(@el).on 'click', 'tr', -> console.log($(@).attr('model')) # CORRECT
render: ->
$(@el).empty()
$(@el).append(@template({data: @collection.getPage()}))
This works, but does this create orphaned click events?
class MyGridView extends Backbone.View
el: '#myGrid'
template: _.template(TableTmpl)
render: ->
$(@el).empty()
$(@el).append(@template({data: @collection.getPage()}))
$('tr',@el).click -> console.log($(@).attr('model'))
UPDATE:
I was missing a parameter to $().on(), which is why it didn't work. I also tried events, which seems like a better way of handling this, which worked like:
class MyGridView extends Backbone.View
el: '#myGrid'
template: _.template(TableTmpl)
events: {'click tr', 'selectModel'}
selectModel: ->
model = $(e.target).parent().attr('model')
console.log(model)
render: ->
$(@el).empty()
$(@el).append(@template({data: @collection.getPage()}))
$('tr',@el).click -> console.log($(@).attr('model'))
Upvotes: 1
Views: 1129
Reputation: 434685
You should be using the events
property for this, that's what it is for:
class MyGridView extends Backbone.View
el: '#myGrid'
events:
'click tr': 'click'
template: _.template(TableTmpl)
render: ->
@$el.empty()
@$el.append(@template({data: @collection.getPage()}))
@
click: ->
console.log($(@).attr('model'))
Also note the switch to @$el
since Backbone already has the jQuery wrapped el
cached and that render
usually returns the view. Furthermore, Backbone views have a $
method that is a shortcut for @$el.find(...)
so you can say @$('tr')
instead of $('tr', @el)
.
Demo: http://jsfiddle.net/ambiguous/ud6dU/
There's no need to mess around with manually binding events (in most cases). Views take care of all that for you using the view's events
and a jQuery delegate
attached to the view's el
.
Upvotes: 1
Reputation: 304
I think you should either use live
instead of on
or you should use backbone's events
object.
Upvotes: 1