我有一个带有marionette插件的Backbone.js应用程序。有一个使用CompositeView(和ItemViews)渲染的集合,我需要按以下方式对其进行排序:
我尝试在onRender钩子中手动对collection.models数组进行排序,然后重新渲染它,但这种集合操作只是“感觉不对”(并导致无限的渲染循环)。
是否有某种更优雅的解决方案来对集合进行排序,使模型的顺序与其他数组中定义的模型ID的顺序相同?
答案 0 :(得分:3)
尝试在集合上使用Backbone.Collection#comparator方法,该方法将使用id数组访问cookie并使用它返回1或-1。
比较器函数有两个模型,如果第一个模型应该在第二个模型之前返回-1,如果它们具有相同的等级,则返回0,如果第一个模型应该在之后,则返回1.
var MyCollection = Backbone.Collection.extend({
comparator: function(model_a, model_b) {
// In real app array comes from cookie
var order = [5, 2, 1, 4, 3],
a_index = order.indexOf(model_a.id),
b_index = order.indexOf(model_b.id);
if (a_index > b_index) {
return 1;
} else if (a_index < b_index) {
return -1;
} else {
return 0;
}
}
});
var my_collection = new MyCollection([
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
{ id: 5 }
]);
alert(my_collection.pluck('id'));
此示例为jsfiddle
答案 1 :(得分:0)
一种方法是使用该ID映射您的“自定义”ID列表并返回集合中的模型:
var items = [
{id: 0, name: '1st', age: 40},
{id: 1, name: '2nd', age: 50},
{id: 2, name: '3rd', age: 60}
];
// order stored in cookie or localstorage ^^
var sorted = [2, 1, 0];
// our source collection
var collection = new Backbone.Collection(items);
// this could be implemented as a collection method if necessary
var sortedCollection = _.map(sorted, function (id) {
return collection.get(id);
});
var sortedIds = sortedCollection.map(function (item) { return item.id })
console.log(sortedIds);
// [2, 1, 0]
<强> jsbin with an example view 强>