2011-11-29 72 views
3

我想按用户可选择的创建日期或优先级对模型集合进行排序。排序具有多个属性的骨干集合

可以按降序或升序选择优先级,但模型将按创建日期按降序进一步排序。

创建日期也可以按降序或升序进行选择,不需要进一步的子订购。

下面是我的代码至今:

comparator: function(task) { 
    var sorter = task.get(root.sortAttr); 
    var subSorter = String.fromCharCode.apply(String, 
    _.map(task.get("created_at").split(""), function (c) { 
     return 0xffff - c.charCodeAt(); 
    }) 
); 

    if(!root.sortAscending) { 
    console.log("desc"); 
    return -sorter + ", " + subSorter; 
    } 
    else { 
    console.log("asc"); 
    return sorter + ", " + subSorter; 
    } 
} 

该代码同时适用于上升和下降的创建日期进行排序,但仅会显示按降序排列优先级。谁能告诉我为什么这是这种情况,我能做些什么来解决这个问题?

回答

1

最后我使用的是基于纯粹的字符串的做法,取得了结果我之后在能够支持基于字符串的排序属性走下赛场方面提供了更大的灵活性。

this.tasks.comparator = function(task) { 
    var priority = (task.get("priority_id")).toString(); 
    var timestamp = task.get("created_at"); 

    if (!sortAscending) { 
    if (sortAttribute == "created_at") return negateString(timestamp); 
    if (sortAttribute == "priority_id") return negateString(negateString(priority) + "-" + negateString(timestamp)); 
    } 
    else { 
    if (sortAttribute == "created_at") return timestamp; 
    if (sortAttribute == "priority_id") return negateString(priority) + "-" + timestamp; 
    } 
} 

this.tasks.sort(); 

凡否定字符串函数是同一个发现here及以下抄录如下:

var negateString = function(s) { 
    s = s.toLowerCase(); 
    s = s.split(""); 
    s = _.map(s, function(letter) { 
    return String.fromCharCode(-(letter.charCodeAt(0))); 
    }); 

    return s.join(""); 
}; 
2

好吧,让我们假设你的模型中有一个属性priority

它简单的解决方法是:

sortOrder: 'asc', 
comparator: function (item) { 
    var timestamp = Date.parse(item.get('created_at')) * 1000; 
    timestamp += item.get('priority'); 

    if (this.sortOrder === 'asc') { 
    return timestamp; 
    } 

    return -timestamp; 
} 

更复杂的解决方案:

sortBy: {'created_at': 'asc', 'priority': 'desc'}, 
comparator: function (item) { 
    var result = 0; 
    for (var field in this.sortBy) { 
     if (field === 'created_at') { 
      result += (this.sortBy[field] === 'asc') 
       ? Date.parse(item.get('created_at')) * 1000 
       : -Date.parse(item.get('created_at')) * 1000; 
     } 

     if (field === 'priority') { 
      result += (this.sortBy[field] === 'asc') 
       ? item.get(field)) * 1000 
       : -item.get(field)) * 1000; 
     } 
    } 

    return result; 
} 

可以扩展sortBy与其他领域的工作,只是解析它为int。注意你的自我,当数字变为>Number.MAX_VALUE或< Number.MIN_VALUE时将失败。

您可以为您的字段实现一个toInt()方法,并且在对象循环中没有if的情况下使用它的所有方法。

result += (this.sortBy[field] === 'asc') 
     ? item.get(field).toInt() * 1000 
     : -item.get(field).toInt() * 1000; 
+1

这帮了很大忙。我仍然没有设法让它工作,因为它总是按照同一方向排序优先级和时间戳,而我需要按照升序优先级排序优先级,然后按每个优先级组中的时间戳排序优先级。 – mmilo

1

骨干现在采取两种模式,你可以比较,只需将第二个参数添加到比较器功能。不知道为什么文档没有更新。

comparator: function (model, model2) { 
    return (model1.get('some_attribute') > model2.get('some_attribute')) ? -1 : 1; 
}