我正在使用Signalr中心订阅服务器上的事件。什么事件被分派到集线器,它成功地将项目添加到Marionette CollectionView。反过来,这会呈现给一个表格。
因为事件表本质上是一个吸墨纸,我希望这些事件的顺序相反,最好只保留n个事件。
Backbone可以“自动”以相反的顺序重新呈现集合吗?
答案 0 :(得分:11)
要按相反的顺序进行收集,我通常使用这样的结构:
_.each(collection.last(collection.length).reverse(), function(model){ });
答案 1 :(得分:8)
https://github.com/marionettejs/backbone.marionette/issues/78
上有关于此主题的主题虽然Backbone在定义比较器后对集合进行了排序,但正如@breischl所指出的那样,当订单发生变化时,Marionette不会自动重新渲染CollectionView。实际上,Marionette会收听集合上的add
事件,会附加一个新的ItemView。
如果您希望CollectionView
始终按相反的时间顺序显示项目,并且您希望添加新项目预先而不是追加,则覆盖appendHtml
中的CollectionView
方法如下:
var MyCollectionView = Backbone.Marionette.CollectionView.extend({
appendHtml: function(collectionView, itemView){
collectionView.$el.prepend(itemView.el);
}
});
如果您希望能够在评论中提到的@dira中插入特定位置,那么在sberryman的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);
答案 2 :(得分: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
属性,并在{{1}中将其用于insertAfter
或类似jQuery (或类似的)方法。
答案 3 :(得分:1)
Backbone会自动按照排序顺序保存集合。如果要使用非默认排序,请在集合中定义comparator()
函数,它将使用该函数。比较器可以采用一个或两个参数see the Backbone documentation来获取详细信息。
然后,您可以在.each()循环中渲染您的集合,它将以正确的顺序出现。但是,按排序顺序向视图添加新项目取决于您自己。
答案 4 :(得分:1)
根据您的描述,您无需以相反的顺序重新呈现集合。只需在该视图中为您的集合添加add
的事件,并让它调用一个函数,该函数只是添加项目并将其预先添加到表格中。
this.collection.on('add', this.addItem);
答案 5 :(得分:0)
您可以在类似的集合中反转模型......
this.collection.models = this.collection.models.reverse()
答案 6 :(得分:0)
如果您使用lodash而不是下划线,您也可以这样做:
_(view.collection.models).reverse();
答案 7 :(得分:0)
由于BackBone不支持集合的反向迭代(并且它只是浪费资源来反转或更糟糕地对集合进行排序),最简单快速的方法是使用for
循环使用集合中模型的索引递减。
for (var i = collection.length - 1; i >= 0; i--) {
var model = collection.models[i];
// your logic
}
使用Underscore排序或反转集合并不是那么优雅,但性能要好得多。尝试比较不同的循环here只是为了知道你为foreach写的是什么成本而不是经典的。