Backbone.js自定义集合排序

时间:2014-09-04 18:52:57

标签: javascript jquery sorting backbone.js marionette

我有一个带有marionette插件的Backbone.js应用程序。有一个使用CompositeView(和ItemViews)渲染的集合,我需要按以下方式对其进行排序:

  1. 用户可以重新排列渲染的ItemViews(使用jQuery可排序插件),并且此用户首选项以模型ID数组的形式保存在cookie中
  2. 在每次重新加载时,我想将获取的集合排序为与上述用户首选项顺序数组相同的顺序。
  3. 我尝试在onRender钩子中手动对collection.models数组进行排序,然后重新渲染它,但这种集合操作只是“感觉不对”(并导致无限的渲染循环)。

    是否有某种更优雅的解决方案来对集合进行排序,使模型的顺序与其他数组中定义的模型ID的顺序相同?

2 个答案:

答案 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