Лучший способ сортировки коллекции в 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
}
})
Ответы
Ответ 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");
};
});