2012-09-17 39 views
0

我有一個ListView與一堆ListItemViews在他們中,使用HTML文件中的模板。我很快發現Backbone希望視圖能夠控制相關元素,以便它可以委託事件等。This answer顯示了一種標準方法,用於像ID一樣自定義外部標記中的常見事物。由模板控制的骨幹列表項視圖標籤

我只是感覺有點奇怪,沒有在我的模板中的外部標籤。如果我想分配一個類,甚至改變元素的類型,那麼在模板IMO中看起來更直觀。在大多數情況下,我可以將視圖分配給現有元素,但對於集合的項目視圖,必須從頭開始創建新的視圖和元素。

我可以使用setElement將一個字符串分配給el並委託事件。但是,稍後在重新渲染控件時(如編輯之後),會中斷與DOM的連接。我的解決辦法是換setSelement,使用jQuery的replaceWith轉用新老元素:

window.Backbone.View.prototype.replaceElement = (element) -> 
    old = @$el 
    @setElement element, true 
    old.replaceWith @$el 

然後我就可以在視圖中使用它:

render:() -> 
    @replaceElement @template @model.toJSON() 
    return @ 

隨着模板:

<script id="actionTemplate" type="text/x-handlebars-template"> 
    <li id="{{id}}"><input type="checkbox" />{{name}}</li> 
</script> 

任何人都可以看到這樣的陷阱嗎?我主要擔心的是,它可能比僅僅從現有標籤中交換html更重要,並且更重要的是它不夠慣用足夠慢?當我真的希望我只在模板中保留標籤的內容時,我可能會愚蠢地打架該框架?

回答

0

您的方法存在的問題是您的視圖的@el仍然是您用新的視圖代替的原始視圖。所以你所有的事件監聽者仍然聽這個舊元素。所以,你必須寫的是這樣的:

window.Backbone.View.prototype.replaceElement = (element) -> 
    old = @$el 
    @setElement element, true 
    old.replaceWith @$el 
    @setElement element 

在這旁邊,如果你只是想創建的項目列表它不是一個好主意,爲每個項目創建一個新的視圖實例。一個有ul元素和迭代你的列表的模板應該就足夠了。

<script id="actionTemplate" type="text/x-handlebars-template"> 
    <ul> 
    {{each items}} 
     <li id="{{id}}"><input type="checkbox" />{{name}}</li> 
    {{/each}} 
    </ul> 
</script> 
+0

我很困惑爲什麼第二個setElement是必需的?查看[Backbone source](http://documentcloud.github.com/backbone/docs/backbone.html#section-155),setElement(newEl,true)將使用undelegateEvents和delegate將所有事件從舊元素中移除到墩。而且您可以將事件設置到DOM中尚未包含的元素上,所以我認爲這不是問題。 – ShawnFumo

+0

對於第二點,每行可以刪除或編輯。例如。在點擊刪除時,它會銷燬該模型。該視圖在此上偵聽,並在不重新呈現整個列表的情況下自行刪除。我也有重新排序等列表視圖。 我可以例如給刪除鏈接唯一的ID,在列表級別聽重新呈現整個列表,但不知道它值得嗎? – ShawnFumo