I'm new to Backbone and am using it with jQuery in Rails. In my view's render
method, I use delegateEvents
to bind an event handler to the "click" event of a button with id btn-go
. This button is itself rendered by the view in question.
Clicking the button stores the form's values in an array and causes the view to re-render. This button is itself rendered by the view in question. This works the first time I click the button, but nothing happens the second time, even though the view does correctly re-render its template.
class MyApp.Views.ChainsNew extends Backbone.View
# @template is defined by a conditional inside render()
render: (step_number) ->
window.model = @model
@step_number = step_number
@template = if @step_number is 1 then JST['chains/new'] else JST['chains/step']
$(@el).html(@template())
@delegateEvents({
'click #btn-go': 'add_step'
})
@
add_step: ->
#divide array into arrays of steps before and after step being edited
steps = @model.get('steps')
array1 = steps.slice(0, @step_number - 1)
array2 = steps.slice(@step_number)
array1.push(@$el.find('textarea').val())
newArray = array2.concat(array1)
@model.set({
steps: newArray
})
The view's render
method is called by the router. As you can see in the code below, the router is listening to the change
event on the model. This causes it to update the URL, which in turn triggers the router's step
method to be called, and it's within that method that the view's render
method is finally called.
class MyApp.Routers.Chains extends Backbone.Router
routes:
'chains/new(/)': 'new'
'chains/new/step/:step_number(/)': 'step'
initialize: ->
# Model
@model = new MyApp.Models.Chain()
@listenTo(@model, "change", ->
@goto_step_number @model.get('steps').length + 1
)
# Views
@view_new = new MyApp.Views.ChainsNew({
model: @model
})
step: (url_step_number) ->
# Before rendering the view, make sure URL & number of steps in model are correctly related
url_step_number = parseInt url_step_number
steps_entered = @model.get('steps').length
if url_step_number > steps_entered + 1
@goto_step_number steps_entered + 1
else
$('#main-container').html(@view_new.render(url_step_number).el)
new: ->
@goto_step_number 1
goto_step_number: (step_number) ->
@.navigate('chains/new/step/' + step_number, trigger: true)
Why doesn't anything happen the second time I click the button? I'm guessing that the event handler hasn't been correctly bound to the button, but I have no idea why.