2012-03-19 208 views
7

我正在使用Signalr集線器訂閱服務器上的事件。什麼事件發送到集線器,它成功地將項目添加到木偶集合視圖。這反過來又呈現爲一張表格。Backbone可以以相反的順序渲染一個集合嗎?

因爲事件表本質上是一個吸墨紙,所以我希望事件按相反的順序,最好只保留n個事件。

可以骨幹'自動'以相反的順序重新呈現集合?

回答

1

通常你會在你的Backbone.View'子類'中進行渲染。所以,你有這樣的:

render: function() { 
    this.collection.each(function(model) { 
    // some rendering of each element 
    }, this); 
} 

this.collection是想必Backbone.Collection子類,所以你可以用它underscore.js methods得到它在任何你喜歡的順序:

this.collection.reverse().each(...) 
this.collection.sort(function(m) { ... }).each(...) 

等等

當然,您從後端獲取單個元素,並且您希望將其插入到正確的位置,而無需重新渲染整個事物!因此,在那種情況下,只需去舊學校,並在元素上插入排序鍵作爲rel屬性或data屬性,並在renderNewItem(或類似)方法中使用insertAfter或類似的jQuery。

+2

不幸的是,reverse()方法在underscore.js方法中可用。 – hbruce 2012-05-31 09:35:54

+0

哈哈好點!不過,我的答案並不是真正的基石。你可以使用不同的方法來反轉它:'_.each(_.toArray(this.collection).reverse(),function(m){...});'。或者,如果你使用咖啡腳本,你可以用-1步寫一個for循環,等等。 – rfunduk 2012-06-04 13:38:45

1

骨幹自動保持集合的排序順序。如果要使用非默認排序,請在您的集合上定義一個comparator()函數,然後它將使用該函數。有關詳細信息,比較器可以採用一個或兩個參數,即see the Backbone documentation

然後,您可以在.each()循環中呈現您的集合,並且它會以正確的順序出現。不過,按照排序順序向視圖添加新項目取決於您。

+0

Dira,好點,它確實使它更容易。但最終你還是得把它們放到正確的位置上。 – 2012-03-20 14:47:09

+1

是的,所以你使用jquery的第n個孩子,之後()或之前() – dira 2012-03-20 21:18:27

1

從您所描述的內容中,您不需要按相反順序重新呈現集合。只需在該視圖中爲您的收藏集添加一個add的事件,並讓它調用一個函數來呈現剛剛添加的項目並將其預先添加到表格中。

this.collection.on('add', this.addItem); 
8

有一個在https://github.com/marionettejs/backbone.marionette/issues/78

有關這個主題的一個線程儘管骨幹不斷的收集整理,一旦你定義了一個比較,因爲@breischl指出,木偶不會自動重新渲染的CollectionView當訂單變更。實際上,Marionette收集了add事件,附加了一個新的ItemView。

如果你希望你的CollectionView始終顯示在反向時間順序的項目,並希望新的項目加入到被前置而不是附加,然後重寫appendHtml方法在CollectionView如下:

var MyCollectionView = Backbone.Marionette.CollectionView.extend({ 
    appendHtml: function(collectionView, itemView){ 
    collectionView.$el.prepend(itemView.el); 
    } 
}); 

如果你想能夠插入特定的位置作爲評論中提到的@dira,在sithman的github上面的鏈接上有一個解決方案發布在這裏,爲了方便我在這裏重現(免責聲明:我還沒有測試過親自下面的代碼):

更改appendHtml到:

appendHtml: function(collectionView, itemView) { 
    var itemIndex; 
    itemIndex = collectionView.collection.indexOf(itemView.model); 
    return collectionView.$el.insertAt(itemIndex, itemView.$el); 
} 

,並添加以下延長jQuery提供insertAt功能:

(function($) { 
    return jQuery.fn.insertAt = function(index, element) { 
    var lastIndex; 
    if (index <= 0) return this.prepend(element); 
    lastIndex = this.children().size(); 
    if (index >= lastIndex) return this.append(element); 
    return $(this.children()[index - 1]).after(element); 
    }; 
})(jQuery); 
+1

請注意,在Marionette 2.x中,appendHtml已更改爲attachHtml。希望能幫助別人!這正是我需要以相反的順序顯示集合,而不會在我的Web應用程序中混淆其他邏輯的順序 – mix3d 2015-04-20 18:47:38

11

要經過收集以相反的順序我通常使用一個建築是這樣的:

_.each(collection.last(collection.length).reverse(), function(model){ }); 
0

您可以在類似的集合中反轉模型所以......

this.collection.models = this.collection.models.reverse() 
0

如果您使用的lodash而不是下劃線你也可以這樣做:

_(view.collection.models).reverse(); 
0

爲骨幹,不支持收集的反向迭代(它只是浪費資源對集合進行反轉或更差的排序)最簡單且最快的方法是使用for循環,該集合中的模型索引減少。

for (var i = collection.length - 1; i >= 0; i--) { 
    var model = collection.models[i]; 

    // your logic 
} 

這並不像使用Underscore對集合進行排序或反轉一樣優雅,但性能要好得多。嘗試比較不同的循環here只是要知道什麼花費你寫foreach而不是經典的。