Reputation: 11473
I'm trying to have a view which can have interchangable templates. So clicking on one of the checkbox rerenders the view. this in fact is happening . but after the view has rerenderd and show the new template correctly im loosing the context and all click bound to this view don't work anymore. http://pastebin.com/bFJ5Yuer
View = require 'views/base/view'
template = require 'views/templates/list_view_a'
module.exports = class OfferListView extends View
autoRender: true
container: "[data-role='content']"
containerMethod: 'html'
initialize: ->
super
@template = template
#views
@delegate 'change', '#list_view_a', @change_list_view
@delegate 'change', '#list_view_b', @change_list_view
@delegate 'change', '#list_view_c', @change_list_view
@delegate 'click', @click_ev
change_list_view: (event) =>
console.log('change')
@template = require 'views/templates/' + event.target.id
@render()
click_ev: =>
console.log('click')
getTemplateData: =>
@collection.toJSON()
Any pointers ?
Upvotes: 0
Views: 814
Reputation: 11473
The call to @delegateEvents didn't do the trick. But thanks for pointing me in a right direction. This was helpful as well. Backbone: event lost in re-render
mind my wrong indentation
View = require 'views/base/view'
template = require 'views/templates/list_view_a'
module.exports = class OfferListView extends View
autoRender: true
container: "[data-role='content']"
containerMethod: 'html'
template: template
initialize: (options) ->
super
#views
change_list_view: (event) =>
@template = require 'views/templates/' + event.target.id
@render()
initEvents: =>
@delegate 'change', '#list_view_a', @change_list_view
@delegate 'change', '#list_view_b', @change_list_view
@delegate 'change', '#list_view_c', @change_list_view
@delegate 'click', @click_ev
click_ev: ->
console.log('click')
render: =>
super
afterRender: =>
super
@initEvents()
Upvotes: 0
Reputation: 3639
Yeah, the call to @render
in change_list_view
is wiping out the element that the events are bound to in the initialize
method.
If you must re-render the view (like if you are changing the template) then you will just have to add a call to @delegateEvents
below the @render
call in change_list_view
.
UPDATE
If you wanted to switch to a subview method, you could probably get rid of that second call to render. Something like this:
# snipped all the outer require js stuff
class InnerViewBase extends Chaplin.View # Or whatever your base view is
autoRender: true
container: "#innerViewContainer"
containerMethod: "html"
initialize: (templateName) ->
@template = require templateName
super
class ListViewA extends InnerViewBase
initialize: ->
super "views/templates/list_view_a"
# Do any event handlers in here, instead of the outer view
# @delegate 'click', @click_ev
class ListViewB extends InnerViewBase
initialize: ->
super "views/templates/list_view_b"
class ListViewC extends InnerViewBase
initialize: ->
super "views/templates/list_view_b"
class OfferListView extends View
autoRender: true
container: "[data-role='content']"
containerMethod: 'html'
initialize: ->
super
@template = template
#views
# Consider changing these three id subscriptions to a class
@delegate 'change', '#list_view_a', @change_list_view
@delegate 'change', '#list_view_b', @change_list_view
@delegate 'change', '#list_view_c', @change_list_view
@delegate 'click', @click_ev
afterRender: ->
# Add a default ListView here if you want
# @subview "ListView", new ListViewA
change_list_view: (event) =>
console.log('change')
# Make a hacky looking map to the subview constructors
viewNames =
"list_view_a": ListViewA
"list_view_b": ListViewB
"list_view_c": ListViewC
@subview "ListView", new viewNames[event.target.id]
click_ev: =>
console.log('click')
getTemplateData: =>
@collection.toJSON()
Upvotes: 1