2012-11-07 59 views
0

我在理解Backbone子視圖中的事件綁定時遇到問題。我的視圖被定義爲如下:Howto綁定Backbone子視圖中的單擊事件

TenantView = Backbone.View.extend({ 
    events: { 
    "click": "setActive" 
    }, 
    initialize: function() { 
    this.parentEl = this.options.parentEl; 
    return this.render(); 
    }, 
    template: new EJS({ 
    url: '/scripts/templates/tenant.ejs' 
    }), 
    render: function() { 
    $(this.parentEl).children('ul').append(this.template.render(this.model)); 
    return this; 
    }, 
    setActive: function(event) { 
    return this.model.set('active', true); 
    } 
}); 

該模板簡單地由一個li的方含一個a。完成這種方式,點擊我的視圖上的事件沒有捕捉到,我的方法setActive永遠不會被觸發。

當我通過el屬性(如el: 'li')擴展我的視圖時,我的(2)個視圖中的一個視圖正常工作並觸發setActive函數。第二種觀點根本沒有反應。如果我在視圖初始化期間忽略el屬性,工作視圖的el屬性指向li,失敗視圖el指向可在頁面中找到的第一個li

可以看出,當涉及到el屬性的含義時,我完全失去了。

問題是,我怎麼能綁定一個點擊視圖到這個視圖setActive函數?

任何人都可以啓發我嗎?

問候 菲利克斯

回答

2

第一件事情,你可以閱讀documentationthis。在那裏給出有關el的說明。

由於TenantViewparentEl屬性,我假設它是從一些parent_view呈現。我會建議像下面的一些方法,並試一試。

var ChildView = Backbone.View.extend({ 
    tagName : "li", // change it according to your needs 

    events : { 
    "click": "setActive" 
    }, 

    initialize : function() { 
    _.bindAll(this, "setActive"); 
    // code to initialize child_view 
    }, 

    render : function() { 
    // as I'm not familiar with the way you are using template, 
    // I've put simple call to render template, but it should render the 
    // content to be kept inside "li" tag 
    this.$el.html(this.template()); 

    return this; 
    }, 

    setActive : function(event) { 
    // code to be executed in event callback 
    } 
}); 


var ParentView = Backbone.View.extend({ 
    el : "#parent_view_el", 

    initialize : function() { 
    // parent view initialization code 
    }, 

    render : function() { 
    // a place from where ChildView is initialized 
    // might be a loop through collection to initialize more than one child views 
    // passing individual model to the view 

    var child_view = new ChildView(); 

    this.$("ul").append(child_view.render().$el); // equivalent to this.$el.find("ul") 

    return this; 
    } 
}); 

希望它有幫助!

+0

颶風,謝謝你的回答。事實上,這幾乎是我正在做的。 parentEl屬性指向CollectionViews el屬性(這是一個ul),以便我可以在ul中呈現我的ChildViews。在我的父級CollectionView中,我遍歷集合模型併爲每個模型創建一個ChildView實例。我有這種感覺,那種做法是完全錯誤的。 – GeorgieF

+0

嗯,這就是我一直以來,對我來說工作得很好:) – Cyclone

+0

閱讀[這](http://stackoverflow.com/questions/5624929/backbone-view-el-confusion)實際上解決了我的問題。看到我下面的評論。再次感謝您的意見。 – GeorgieF

0

你有一種禁用骨幹通過引入您的parentEl財產和規避視圖元素的創建自然的行爲。你基本上從來沒有把elz屬性視爲任何東西。

如果我的代碼正確,TenantView是租戶列表中的單個列表項。

在你TenantView,你可以做這個建在事件槓桿骨幹:

render: function() { 
    this.setElement(this.template.render(this.model)); 
    $(this.parentEl).children('ul').append(this.$el); 
    return this; 
} 

setElement功能將使用您的返回值template功能的電纜鋪設工作的意見元素,並且還設置了事件你。在文檔中,建議使用setElement而不是僅僅爲el屬性指定一些內容。還有一個漂亮的$el屬性,它將包含視圖元素的緩存jQuery(或Zepto)對象。

走得更在主幹路個人而言,我會考慮這樣的事情:

var TenantView = Backbone.View.extend({ 
    // ========= 
    // = Setup = 
    // ========= 

    events: { 
     "click": "setActive" 
    }, 

    template: new EJS({ 
     url: '/scripts/templates/tenant.ejs' 
    }), 

    // ============= 
    // = Lifecycle = 
    // ============= 

    initialize: function(model, options) { 
     this.render(); 
    }, 

    render: function() { 
     var content = this.template.render(this.model); 
     this.$el.html(content); 
     return this; 
    }, 

    // ========== 
    // = Events = 
    // ========== 

    setActive: function(event) { 
     return this.model.set('active', true); 
    } 

}); 


var TenantList = Backbone.View.extend({ 

    // ========= 
    // = Setup = 
    // ========= 

    id: "tenantList", 
    tagName: "ul", 

    // ============= 
    // = Lifecycle = 
    // ============= 

    initialize: function() { 
     this.render(); 
    }, 

    render: function() { 
     if (this.collection.length > 0) { 
      this.renderChildren(); 
     } 
    }, 

    renderChildren: function() { 
     var that = this; 

     this.collection.each(function(tenant) { 
      that.$el.append(new TenantView(tenant).$el); 
     }); 
    } 
}); 
+0

Torsten,謝謝你的回覆。 setElement似乎在渲染過程中正確設置了我的視圖的el屬性。不幸的是,點擊事件並沒有發生。我認爲我在CollectionView中渲染ChildViews的整個方法是完全錯誤的。 – GeorgieF

+0

那麼在一種方式...骨幹種類的期望你有一個元素初始化後,只填充與渲染功能。理論上'setElement'函數應該處理事件。你使用哪個版本的骨幹網? –

+0

我正在使用0.9.2。到目前爲止,解決這個問題的方法是將ChildView的'tagname'設置爲'li'。然後從模板中刪除li。我將我的ChildView的渲染方法更改爲:this.el.innerHTML = this.template.render(this.model),並將我的CollectionView的渲染方法更改爲:$(this.el).children('ul')。 append(viewInstance.render()。el)viewInstance的迭代位置。我仍然不確定這種方法是否正確。 – GeorgieF