14

我正在尝试对一个集合进行排序Marionette.CompositeView
我有一个看起来像这样的集合:

[
   {id: 1, name: 'bar'},
   {id: 2, name: 'boo' },
   {id: 3, name: 'foo' }
]

我需要以相反的顺序按 id 对集合进行排序。
实际上它仅在我重新加载页面时才有效。
当我添加一个新模型时,新项目显然是随机添加到列表中的。
如果我刷新页面,它们将得到很好的排序。

我的问题是:
1)添加新模型时如何解决问题?
2)有可能改进代码吗?


这是我的代码:

return Marionette.CompositeView.extend({

    initialize: function () {
        this.collection.fetch();
    },

    onRender: function () {
        var collection =  this.collection;

        collection.comparator = function (collection) {
            return - collection.get('id');
        }
    },

    onSuccess: function () {
        this.collection.add(this.messageModel);
        this.collection.sort(); // the messageModel seems to be added 
                                // apparently randomly to the list. 
                                // only if I refresh the page it will be ok
    }
})
4

3 回答 3

14

对于 Marionette >= 2.0CollectionView并且CompositeView 默认保持排序

对于 Marionette < 2.0 和 >= 1.3.0

var MySortedView = Backbone.Marionette.CollectionView.extend({

  // ...

  appendHtml: function(collectionView, itemView, index) {
    // Already sorted when buffering.
    if (collectionView.isBuffering) {
      Backbone.Marionette.CollectionView.prototype.appendHtml.apply(this, arguments);
    }
    else {
      var childrenContainer = $(collectionView.childrenContainer || collectionView.el);
      var children = childrenContainer.children();
      if (children.size() === index) {
        childrenContainer.append(itemView.el);
      } else {
        childrenContainer.children().eq(index).before(itemView.el);
      } 
    }
  }

});

对于 Marionette < 2.0 或 < 1.3.0(与之前相同,没有缓冲):

var MySortedView = Backbone.Marionette.CollectionView.extend({

  // ...

  appendHtml: function(collectionView, itemView, index) {
    var childrenContainer = $(collectionView.childrenContainer || collectionView.el);
    var children = childrenContainer.children();
    if (children.size() === index) {
      childrenContainer.append(itemView.el);
    } else {
      childrenContainer.children().eq(index).before(itemView.el);
    } 
  }

});

CollectionView 和 CompositeView 也是一样的。

于 2012-07-26T06:37:12.893 回答
3

我相信 Marionette 的人正在考虑将其构建到 Marionette 中,但在那之前,我已经构建了一个名为Sorted的小混入,您可以将其混入您的CollectionViewCompositeView类中。长期以来,它在Gitter的生产环境中被大量使用,我们发现它运行良好。

于 2014-04-02T18:17:32.590 回答
1

您可以在创建集合时声明 .comarator 吗?从您的代码中, .comarator 仅存在于var collectiononRender 函数内的局部变量中。如果定义正确,集合必须自动排序,添加新模型后无需调用 .sort

var Chapters = new Backbone.Collection({
    comparator = function(chapter) {
        return chapter.get("id");
    };
});
于 2012-07-26T00:23:10.327 回答