如何在Backbone.js/underscore.js中的比较器中实现多级排序?

dla*_*tte 5 javascript backbone.js underscore.js

想象一个模型/集合,如:

var AModel = Backbone.Model.extend({
    defaults: {
        a: 'a string',
        b: 'another string',
        c: 'yet another string'
    }
});

var ACollection = Backbone.Collection.extend({
    model: AModel,
    comparator: function(amodel) {
        ...
    }
});
Run Code Online (Sandbox Code Playgroud)

我怎么能写一个比较器来实现多级排序?我想作为排序依据AModela属性,然后通过它的b属性,然后通过它的c属性.

我已经把一个比较器看起来像这样,但我想知道是否有更好/更聪明的方法?

comparator: function(amodel) {
    var s = '',
        assumed_max_length_of_any_attribute = 30;

    s += amodel.get('a');
    while (s.length < assumed_max_length_of_any_attribute) {
        s += ' ';
    }

    s += amodel.get('b');
    while (s.length < assumed_max_length_of_any_attribute) {
        s += ' ';
    }

    s += amodel.get('c');
    while (s.length < assumed_max_length_of_any_attribute) {
        s += ' ';
    }

    return s;
}
Run Code Online (Sandbox Code Playgroud)

然后,s用空格正确填充,并且应该是具有多个级别的"词汇"顺序.但是,与python稳定的多级排序之类相比,这一切都感觉非常粗糙(如果以上在python中有类似的等价物):

collection.sort(key=lambda x: x.get('c'))
collection.sort(key=lambda x: x.get('b'))
collection.sort(key=lambda x: x.get('a'))
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?

knu*_*nub 8

骨干文档说:

比较器函数可以定义为sortBy(传递一个接受单个参数的函数),或者作为一个排序(传递一个需要两个参数的比较器函数).

http://documentcloud.github.com/backbone/#Collection-comparator

您可以使用第二种方式并根据给定的两个元素实现比较.

也许是这样的:

helper: function (c1, c2) {
    if (c1 < c2) return -1;
    if (c1 > c2) return +1;
    return 0;
}
comparator: function (model1, model2) {
    return _.reduce(["c", "b", "a"], function (acc, comp) {
        return acc !== 0 ? acc : this.helper(model1[comp], model2[comp])
    }, 0);
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,这个功能是在一周前的骨干0.9中引入的.值得一读的是版本历史. (3认同)