Подтвердить что ты не робот

Лучший способ сортировки коллекции в CompositeView

Я пытаюсь сортировать коллекцию в 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
    }
})
4b9b3361

Ответ 1

Для Marionette >= 2.0, CollectionView и 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.

Ответ 2

Я считаю, что ребята из Marionette рассматривают возможность создания этого в Marionette, но до этого времени я создал небольшой mixin под названием Сортировка, которые вы можете смешивать в своих классах CollectionView и CompositeView. Он долгое время использовался в производственной среде для Gitter, и мы находим, что он работает очень хорошо.

Ответ 3

Можете ли вы объявить .comparator при создании коллекции? из вашего кода .comparator существует только для локальной переменной var collection внутри функции onRender. Если правильно определено, сбор должен быть автоматически отсортирован, и вам не нужно вызывать .sort после добавления новой модели

var Chapters = new Backbone.Collection({
    comparator = function(chapter) {
        return chapter.get("id");
    };
});