Backbone.js集合比较器按多个字段排序?

Har*_*rry 42 javascript sorting backbone.js

  this.col = Backbone.Collection.extend({
    model: M,
    comparator: function(item) {
      return item.get("level");
    }
  });
Run Code Online (Sandbox Code Playgroud)

以上代码按级别对项目进行排序.我想按级别排序,然后按标题排序.我能这样做吗?谢谢.

Bo *_*nes 73

@amchang87's answer definitely works, but another that I found worked is simply returning an array of the sortable fields:

this.col = Backbone.Collection.extend({
    model: M,
    comparator: function(item) {
      return [item.get("level"), item.get("title")]
    }
});
Run Code Online (Sandbox Code Playgroud)

I haven't tested this in multiple browsers yet as I think it relies on JS' behavior in sort order for arrays (based on their contents). It definitely works in WebKit.

  • 自2012年初以来,支持排序式比较器.只需接受2个参数并返回-1,0或1. https://github.com/documentcloud/backbone/commit/6b3ff7b0359510917d9ead8c8e16a7457eef05ef (5认同)
  • 请注意(至少在Webkit中)这两个字段将被比较为字符串.如果您正在尝试进行数字排序,那么最终会得到1分,10分,2分,20分,200分等. (5认同)
  • @RobW:不完全是,它实际上最终会比较字符串化数组而不是它们的元素,所以这个答案是不正确的,只会偶然发生. (4认同)
  • 如此直截了当,这种技术是.以下是CoffeeScript中的一个示例:https://gist.github.com/jhabdas/9822535 (2认同)

hyo*_*ong 7

字符串连接在按升序排序多个字段时工作正常,但它对我不起作用,因为1)我必须支持每个字段的asc/desc和2)某些字段是数字字段(即,我希望10后来2如果它是提升的).所以,下面是我使用的比较器功能,可以满足我的需求.它假设主干集合具有一个赋值为'sortConfig'的变量,该变量是一个带有字段名称和排序顺序方向的JSON对象数组.例如,

{
    "sort" : [
        {
            "field": "strField",
            "order": "asc"
         },
         {
             "field": "numField",
             "order": "desc"
         },
         ...
     ]
}
Run Code Online (Sandbox Code Playgroud)

将上面的JSON对象指定为集合的"sortConfig",下面的函数将首先按strField按升序排序,然后按降序排序按numField排序等.如果未指定排序顺序,则默认按升序排序.

multiFieldComparator: function(one, another) {
    // 'this' here is Backbone Collection
    if (this.sortConfig) {
        for (var i = 0; i < this.sortConfig.length; i++) {
            if (one.get(this.sortConfig[i].field) > another.get(this.sortConfig[i].field)) {
                return ("desc" != this.sortConfig[i].order) ? 1 : -1;
            } else if (one.get(this.sortConfig[i].field) == another.get(this.sortConfig[i].field)) {
                // do nothing but let the loop move further for next layer comparison
            } else {
                return ("desc" != this.sortConfig[i].order) ? -1 : 1;
            }
        }
    }
    // if we exited out of loop without prematurely returning, the 2 items being
    // compared are identical in terms of sortConfig, so return 0
    // Or, if it didn't get into the if block due to no 'sortConfig', return 0
    // and let the original order not change.
    return 0;
}
Run Code Online (Sandbox Code Playgroud)