7

我正在使用 Signalr 集线器订阅服务器上的事件。将什么事件分派到集线器,它成功地将项目添加到 Marionette CollectionView。反过来,这会呈现到表格中。

因为事件表本质上是一个吸墨纸,所以我希望事件以相反的顺序排列,最好只保留 n 个事件。

Backbone 可以“自动”以相反的顺序重新渲染集合吗?

4

8 回答 8

11

为了以相反的顺序进行收集,我通常使用这样的结构:

_.each(collection.last(collection.length).reverse(), function(model){ });
于 2012-12-14T10:35:11.057 回答
8

在https://github.com/marionettejs/backbone.marionette/issues/78上有一个关于此主题的主题

正如@breischl 指出的那样,尽管 Backbone 在定义比较器后会保持集合的排序,但当订单更改时,Marionette 不会自动重新渲染 CollectionView。事实上,Marionette 会监听add集合上的事件并附加一个新的 ItemView。

如果您希望CollectionView始终以相反的时间顺序显示项目,并且希望添加的新项目被添加而不是appended,然后覆盖您的方法,如下所示:appendHtmlCollectionView

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

如果您希望能够像评论中提到的@dira 那样在特定位置插入,sberryman 在上面的链接中发布了一个解决方案,为了方便起见,我在此处复制了该解决方案(免责声明:我没有测试下面的代码亲自):

将 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);
于 2012-05-09T04:46:04.013 回答
1

通常你会在你Backbone.View的“子类”中进行渲染。所以你有类似的东西:

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

this.collection大概是一个Backbone.Collection子类,因此您可以在其上使用underscore.js 方法以您喜欢的任何顺序获取它:

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

等等。

当然,您从后端获取单个元素,并且您希望将其插入正确的位置,而无需重新渲染整个内容!因此,在这种情况下,只需回到旧学校并将您的排序键作为rel属性或data属性插入元素,并在您的(或类似的)方法中使用它insertAfter或与 jQuery类似。renderNewItem

于 2012-03-19T13:29:06.113 回答
1

Backbone 自动将 Collections 保持在排序顺序。如果您想使用非默认排序,comparator()请在您的 Collection 上定义一个函数,它将使用该函数。比较器可以采用一个或两个参数,有关详细信息,请参阅 Backbone 文档

然后,您可以在 .each() 循环中呈现您的集合,它会以正确的顺序出现。不过,按排序顺序将新项目添加到视图中取决于您。

于 2012-03-20T00:00:57.370 回答
1

根据您的描述,您不需要以相反的顺序重新渲染集合。只需在该视图中为您的集合添加一个事件,add并让它调用一个函数,该函数呈现刚刚添加的项目并将其添加到表中。

this.collection.on('add', this.addItem);
于 2012-03-20T05:09:04.310 回答
0

如果你使用lodash而不是下划线,你也可以这样做:

_(view.collection.models).reverse();
于 2015-03-18T07:23:37.540 回答
0

您可以像这样在集合中反转模型...

this.collection.models = this.collection.models.reverse()
于 2014-12-10T06:29:27.923 回答
0

由于 BackBone 不支持集合的反向迭代(并且对集合进行反向或更糟糕的排序只是浪费资源),因此最简单和最快的方法是for在集合中的模型上使用具有递减索引的循环。

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

    // your logic
}

它不像使用下划线对集合进行排序或反转那样优雅,但性能要好得多。尝试在这里比较不同的循环,以了解您编写 foreach 而不是经典 for 的成本。

于 2015-09-23T12:47:13.263 回答