2012-03-03 91 views
8

我有一個視圖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。這看起來是正確的,但我很好奇,如果有更好的解決方法。

回答

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)裏面的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

1

你的問題是,delegateEvents需要一個單一的,不變的元素爲您的觀點。因爲您的render函數每次都會創建一個新元素,所以當您單擊由render生成的元素時,從不會觸發由delegateEvents所做的綁定。

幸運的是,當前版本的Backbone提供了一個setElement method,它將用您提供的參數重新指定您的元素,然後它會自動調用delegateEvents

+0

我應該明確的一件事是我在一個儀表板中實例化了多個小部件。因此,重新分配元素並不完全是我想要的,我想。 – picardo 2012-03-03 22:11:32