8

我有一个名为DashboardView实例化多个WidgetViews 的视图。每个小部件都需要有自己的事件绑定。据我所知,当视图被渲染并添加到父视图时,这些绑定会丢失,即:

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小部件元素上的点击事件现在丢失了。有没有更好的方法将嵌套视图混合到父视图中,同时确保子视图上的事件处理程序被正确引导?

我在这篇文章中看到了这个问题的一个解决方案。这看起来是对的,但我很好奇是否有更优雅的方法来解决这个问题。

4

2 回答 2

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'render方法中,您通过模板使用其模型的数据填充@el(视图的根元素)。(请注意我如何只编译一次模板- 无需在每次渲染操作时编译模板。)

(2) 在 内部DashboardView,您将小部件的根元素 - @el- 附加到 DOM。

问题是视图的事件委托给它的根元素 - @el。因此,您希望显式使用根元素:在内部render,填充它,然后将其附加到 DOM。

于 2012-03-03T22:47:57.810 回答
1

您的问题是delegateEvents您的视图需要一个单一的、不变的元素。因为您的render函数每次都会创建一个新元素,所以delegateEvents当您单击render.

幸运的是,当前版本的 Backbone 提供了一种setElement方法,可以使用您提供的参数重新分配您的元素,然后它会自动调用delegateEvents.

于 2012-03-03T21:50:11.813 回答