Backbone.js嵌套视图中的事件

问题描述:

我有一个视图DashboardView,它实例化了多个WidgetView。每个小部件都需要有自己的事件绑定。到目前为止,我所知道的,当视图渲染并添加到父视图,即这些绑定迷路:Backbone.js嵌套视图中的事件

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。这看起来是正确的,但我很好奇,如果有更好的解决方法。

试试这个:

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)里面的WidgetViewrender方法,您填充@el(视图的根元素)及其模型数据通过模板。 (同时注意我如何编译模板只有一次 - 没有必要编译模板上的每个渲染操作。)

(2)DashboardView内,你追加widget的根元素 - @el - 到DOM 。

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

+0

这正是我所寻找的。谢谢! – picardo 2012-03-03 23:03:36

+4

你可以通过使用['(w)=>'](http://coffeescript.org/#fat_arrow)来避免'context'的东西。 '@ collection'应该是Underscore-ified,所以'@collection.each(w)=>'是另一种选择。 – 2012-03-04 01:16:29

+0

@mu酷':)'不知道胖箭头。 – 2012-03-04 02:23:15

你的问题是,delegateEvents需要一个单一的,不变的元素为您的观点。因为您的render函数每次都会创建一个新元素,所以当您单击由render生成的元素时,从不会触发由delegateEvents所做的绑定。

幸运的是,当前版本的Backbone提供了一个setElement method,它将用您提供的参数重新指定您的元素,然后它会自动调用delegateEvents

+0

我应该明确的一件事是我在一个仪表板中实例化了多个小部件。因此,重新分配元素并不完全是我想要的,我想。 – picardo 2012-03-03 22:11:32