2012-05-30 56 views
2

我有一個相當簡單的表格,使用Backbone Marionette CompositeView創建。該表的唯一要求是顯示數據並允許用戶通過單擊標題行對其進行排序。在對錶進行排序時,用於排序標題列的列標有類,以允許使用CSS顯示箭頭(例如'class =「sort asc」')。骨幹木偶複合視圖「事件殭屍」

這是問題:當單擊標題行時,傳遞給回調(通過event.target)的元素不是DOM上的表的一部分。相反,使用Chrome的調試工具,看起來目標元素實際上是模板腳本塊的一部分,而不是用戶實際看到的元素。

我現在最好的解決方法是通過從模板中的克隆中檢索唯一信息來查找實際附加到DOM的元素。

這裏的複合視圖代碼(從一個借用德里克貝利的樣品小提琴的):

// The grid view 
var GridView = Backbone.Marionette.CompositeView.extend({ 
    tagName: "table", 
    template: "#grid-template", 
    itemView: GridRow, 

    events: { 
     'click th': 'doSort' 
    }, 

    doSort: function(event) { 
     var target = $(event.target); 
     this.collection.sortByField(target.data('sortby')); 

     target.parent('tr').find('.sort').removeAttr('class'); 
     target.addClass('sort ' + this.collection.sortdir); 
     debugger; // NOTE: no change to elements in the DOM. WTH? 

     target = this.$('[data-sortby=' + target.data('sortby') + ']'); 
     target.parent('tr').find('.sort').removeAttr('class'); 
     target.addClass('sort ' + this.collection.sortdir); 
     debugger; // NOTE: DOM updated. 
    }, 

    appendHtml: function(collectionView, itemView) { 
     collectionView.$("tbody").append(itemView.el); 
    } 
}); 

模板是簡單,以及:

<script id="grid-template" type="text/template"> 
    <thead>   
     <tr> 
      <th data-sortby="username">Username</th> 
      <th data-sortby="fullname">Full Name</th> 
     </tr> 
    </thead> 
    <tbody></tbody> 
</script> 

修飾以Derek的原始演示小提琴的叉證明問題可以在這裏找到: http://jsfiddle.net/ccamarat/9stvM/14/

我蜿蜒了一下。我的問題是,我似乎有一個產生了殭屍視圖的種類;這是一個jQuery/Backbone/Underscore錯誤,或者我只是想解決這個問題嗎?

**編輯** 這裏展示這兩個元素的不同層次家長的控制檯輸出:

console.log(target, targetb): 
    [<th data-sortby="username" class="sort asc">Username</th>] [<th data-sortby="username">Username</th>] 

console.log(target.parents(), targetb.parents()): 
    [<tr>…</tr>, <thead>…</thead>] [<tr>…</tr>, <thead>…</thead>, <table>…</table>, <div id="grid">…</div>, <body>…</body>, <html>…</html>] 

console.log(target === targetb): 
    false 
+0

你能更具體地瞭解問題嗎?你已經以非常詳細的方式提到了幾個潛在的問題,但是隻提出一個非常簡短的問題,沒有詳細說明殭屍視圖。你想解決哪個問題?你爲什麼認爲你有殭屍的觀點?你看到什麼殭屍,在哪裏? –

+0

也 - 我已經在最新版本的Chrome中運行您的示例小提琴,並且它工作正常。你說DOM沒有更新的評論......當我運行它時,它已經被更新了。你使用什麼瀏覽器/版本? –

+0

如果聽起來有不止一個問題比我做了一個糟糕的工作來解釋我自己。唯一的問題是我稱之爲殭屍視圖。我稱之爲的原因是,至少在我的設置中,在第一個斷點(使用event.target)更新的元素*不是*與第二個元素相同(使用this。$ el.find( ))。我正在使用最新版本的Chrome進行測試,並且我已經能夠在兩臺不同的計算機上進行兩次複製。 –

回答

2

我沒有看到一個殭屍觀點的證據。

我創建了一個代碼的分支,並放入了一些額外的日誌記錄來檢查視圖實例,並且我沒有看到任何殭屍。每次都使用相同的GridView實例。孩子們的意見在每次分類時都會正確關閉。

http://jsfiddle.net/derickbailey/hadbf/4/

問題您眼見爲實可能通過使用target = $(e.target)targetb = this.$(...)造成的。這些是兩個非常不同的陳述,從DOM元素的兩個完全不同的來源開始工作。

target = $(e.target)的首次使用直接從DOM運行。你在被點擊的目標上運行一個選擇器,它只是將該DOM元素包裝在一個jQuery選擇器對象中。

第二次使用的targetB = this.$(...)使用骨幹視圖的$el做一個發現:this.$el.find("...")這是會返回基於視圖的EL結果。視圖的$ eL恰好包含屬於DOM的元素。但$ el與e事件不是同一個對象,因此您將永遠不會以target === targetb爲真。

......除非我完全誤解了這個問題(現在看起來很可能),我認爲這裏沒有問題。

+0

Your fiddle讓我思考了調用sort()時會發生什麼 - 底層集合發生了變化,觸發了所有子視圖的關閉 - 這是有道理的。但是,我並不期望它重置標題行,但這正是發生的情況。在調用'event.target'後,'sort()'不再指向DOM上的一個元素,因爲'render()'操作調用'renderModel()',它從模板重新生成視圖,銷燬'event.target '在這個過程中。 –

+0

所以我創建了一個孤立的引用,而不是殭屍視圖。我可以通過從CollectionView而不是複合視圖繼承,重寫initialize()函數並在模板中手動讀取。 感謝您的時間! –

+0

我現在看到......發生這種情況是因爲CompositeView從CollectionView擴展而來,並且CollectionView有一個內置的事件處理程序,通過在集合重置時調用.render方法來重新呈現該事件處理程序。排序集合會重置集合(我認爲),因此整個合成視圖會重新呈現。你可以重寫複合視圖的'initialEvents'方法來改變這種行爲:http://derickbailey.github.com/backbone.marionette/docs/backbone.marionette.html#section-21鏈接是CollectionView,但只是添加該方法給你的CompositeView覆蓋。 –