我有一个名为DashboardView
的视图,它实例化了多个WidgetView
。每个小部件都需要有自己的事件绑定。据我所知,当渲染视图并将其添加到父视图时,这些绑定会丢失,即:
class DashboardView extends Backbone.View
constructor: ->
context = @
_.each @collection, (w)->
dv = new app.WidgetView(model: w)
context.$el.append(dv.render())
class WidgetView extends Backbone.View
events:
"click .config" : "config_widget"
render: ->
_.template($("#widget-template").html(), @model)
这样做,小部件的.config
元素上的点击事件现在丢失了。是否有更好的方法将嵌套视图混合到父级中,同时确保子视图上的事件处理程序正确引导?
我在this article中遇到过这个问题的一个解决方案。这看起来是正确的,但我很好奇是否有更优雅的方法来解决这个问题。
答案 0 :(得分:10)
试试这个:
class DashboardView extends Backbone.View
constructor: ->
@collection.each ( w ) =>
dv = new app.WidgetView( model: w )
@$el.append dv.render().el // Append widget's @el explicitly
class WidgetView extends Backbone.View
tagName: 'div' // or whatever your view's root element is
template: _.template $( "#widget-template" ).html() // pre-compile template
events:
"click .config": "config_widget"
render: ->
@$el.html @template @model.toJSON() // append template to @el
return this // return view
所以,这个想法是这样的:
(1)在WidgetView
的{{1}}方法中,您通过模板填充render
(视图的根元素)及其模型的数据。 (并注意我如何编译模板仅一次 - 不需要在每个渲染操作上编译模板。)
(2)在@el
内,将小部件的根元素 - DashboardView
- 附加到DOM。
问题是视图的事件委托给它的根元素 - @el
。因此,您希望显式使用根元素:在@el
内,填充它,然后将其附加到DOM。
答案 1 :(得分:1)
您的问题是delegateEvents
期望您的视图有一个不变的元素。由于您的render
函数每次都会创建一个新元素,因此当您单击delegateEvents
生成的元素时,render
所做的绑定永远不会被触发。
幸运的是,Backbone的当前版本提供setElement
method,它会使用您提供的参数重新分配您的元素,然后它会自动调用delegateEvents
。