Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Backbone.js 主干能否以相反的顺序呈现集合?_Backbone.js_Marionette - Fatal编程技术网

Backbone.js 主干能否以相反的顺序呈现集合?

Backbone.js 主干能否以相反的顺序呈现集合?,backbone.js,marionette,Backbone.js,Marionette,我正在使用信号集线器订阅服务器上的事件。如果事件被调度到中心,它将成功地将项目添加到木偶收集视图。这将依次呈现到表中 因为事件表本质上是一个记事本,所以我希望事件的顺序相反,最好只保留n个事件 主干能否“自动”按相反顺序重新呈现集合?通常,您将在主干中进行呈现。查看“子类”。所以你有这样的想法: render: function() { this.collection.each( function(model) { // some rendering of each element

我正在使用信号集线器订阅服务器上的事件。如果事件被调度到中心,它将成功地将项目添加到木偶收集视图。这将依次呈现到表中

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


主干能否“自动”按相反顺序重新呈现集合?

通常,您将在主干中进行呈现。查看“子类”。所以你有这样的想法:

render: function() {
  this.collection.each( function(model) {
    // some rendering of each element
  }, this );
}
this.collection
可能是一个
主干.collection
子类,因此您可以在其上使用它,以任意顺序获取它:

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


当然,您将从后端获取单个元素,并且希望在不重新渲染整个内容的情况下将其插入正确的位置!因此,在这种情况下,只需老一套,在元素上插入排序键作为
rel
属性或
data
属性,并在
renderNewItem
方法中使用该属性来
insertAfter
或类似的jQuery。如果要使用非默认排序,请在集合上定义一个
comparator()
函数,它将使用该函数。比较器可以采用一个或两个参数作为详细信息


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

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

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

网站上有一个关于这个主题的帖子

正如@breischl所指出的,尽管主干会在定义比较器后对集合进行排序,但当顺序发生变化时,木偶不会自动重新呈现CollectionView。事实上,木偶监听集合上的
add
事件,并附加一个新的ItemView

如果希望您的
CollectionView
始终以逆时间顺序显示项目,并且希望添加的新项目是预先添加的,而不是追加的,那么请覆盖
CollectionView
中的
appendHtml
方法,如下所示:

var MyCollectionView = Backbone.Marionette.CollectionView.extend({
  appendHtml: function(collectionView, itemView){
    collectionView.$el.prepend(itemView.el);
  }
});
如果您希望能够在评论中提到的@dira的特定位置插入,sberryman在github上面的链接上发布了一个解决方案,为了方便起见,我在这里复制了该解决方案(免责声明:我没有亲自测试下面的代码):

将HTML更改为:

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);
(函数($){
return jQuery.fn.insertAt=函数(索引,元素){
var指数;
如果(index=lastIndex)返回此.append(元素);
在(元素)之后返回$(this.children()[index-1]);
};
})(jQuery);

要以相反的顺序遍历集合,我通常使用如下结构:

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

你可以在这样一个集合中反转你的模型

this.collection.models = this.collection.models.reverse()
如果使用下划线代替下划线,也可以执行以下操作:

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

由于主干网不支持集合的反向迭代(而且对集合进行反向或更糟的排序只会浪费资源),因此最简单、最快的方法是使用
for
循环,在集合中的模型上减少索引

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

    // your logic
}

它不像使用下划线排序或反转集合那样优雅,但性能要好得多。尝试比较不同的循环,只是为了知道编写foreach而不是classic的成本。

Dira,很好的一点,这确实让编写更容易。但是最终你还是要让它们在正确的位置进入DOM。是的,所以你使用了jquery的第n个子项和after()或before(),不幸的是,下划线.js方法中没有可用的reverse()方法。哈哈,这是一个很好的观点!不过,这并不是我答案的基础。您可以使用不同的方法来反转它:
.each(u.toArray(this.collection).reverse(),function(m){…})。或者,如果您使用的是coffeescript,您可以只编写一个带有-1步骤的for循环,等等。请注意,在Marionette 2.x中,appendHtml更改为attachHtml。希望能帮助别人!这正是我所需要的,以相反的顺序显示集合,而不会扰乱我的web应用程序中其他逻辑的顺序