Javascript 按多列对网格进行排序?

Javascript 按多列对网格进行排序?,javascript,jquery,sorting,slickgrid,Javascript,Jquery,Sorting,Slickgrid,我刚刚开始为一个项目进行测试,我对它的性能印象深刻。我的一个要求是对多个列进行排序。我还没有完全了解Slickgrid中的Dataview,所以我可能遗漏了一些明显的东西,但是有没有办法在多个列上对网格进行排序?即使UI不能处理多个排序,我也希望能够按顺序调用一个函数,加上升序或降序。我可以用,但它没有分组(项目的另一个要求) 在最坏的情况下,我将求助于在服务器上进行排序,并将静态排序的内容返回给客户端。您可以链接排序比较器来进行多列排序。而不是做 function comparerOnCol1

我刚刚开始为一个项目进行测试,我对它的性能印象深刻。我的一个要求是对多个列进行排序。我还没有完全了解Slickgrid中的Dataview,所以我可能遗漏了一些明显的东西,但是有没有办法在多个列上对网格进行排序?即使UI不能处理多个排序,我也希望能够按顺序调用一个函数,加上升序或降序。我可以用,但它没有分组(项目的另一个要求)


在最坏的情况下,我将求助于在服务器上进行排序,并将静态排序的内容返回给客户端。

您可以链接排序比较器来进行多列排序。而不是做

function comparerOnCol1(a, b) {
  return a["col1"] - b["col1"];
}

function comparerOnCol2(a, b) {
  return a["col2"] - b["col2"];
}
你能行

// sort by col1, then col2
function combinedComparer(a, b) {
  return comparerOnCol1(a, b) || comparerOnCol2(a, b);  // etc.
}
或者直接内联实现它


就在UI中反映排序顺序而言,虽然您不能直接这样做,但您可以通过在排序依据的列定义上设置“HeaderCSClass”并让它们显示箭头(或者以其他方式指示排序列)来应用排序指示符。

这里有一个使用“multiColumnSort”选项的示例

但是我认为它不起作用,因为args.sortCols始终是1的数组

[编辑] 为了让它工作,我需要在单击列标题之前按住shift键(不是很直观的IMHO)
另请参见:

我花了一段时间试图用dataview解决这个问题(没有shift键的把戏),我想我找到了解决方法

使用单列排序
{multiColumnSort:false}
并将排序参数存储在闭包中。如果字段相等,则遵循上一个比较器

var currentSortCmp = null;  
grid.onSort.subscribe(function (e, args) {

    // declarations for closure
    var field = args.sortCol.field;
    var sign = args.sortAsc ? 1 : -1;
    var prevSortCmp = currentSortCmp;

    // store closure in global
    currentSortCmp = function (dataRow1, dataRow2) {

        var value1 = dataRow1[field], value2 = dataRow2[field];

        //if equal then sort in previous closure (recurs)
        if (value1 == value2 && prevSortCmp)
            return prevSortCmp(dataRow1, dataRow2);

        return (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign;
    };
    dataView.sort(currentSortCmp);

    grid.invalidate();
    grid.render();      
});

记住所有以前的订单。只是工作而已。工作正常。

我在dataView中使用了多列排序。也是最容易理解的。这是github中的示例,只是我必须为dataView.sort()再传递一个参数。它总是正确的,您可以在函数中处理排序方向

grid.onSort.subscribe(function (e, args) {
    gridSorter(args.sortCols, dataView);
});

function gridSorter(sortCols, dataview) {
    dataview.sort(function (row1, row2) {
        for (var i = 0, l = sortCols.length; i < l; i++) {
            var field = sortCols[i].sortCol.field;
            var sign = sortCols[i].sortAsc ? 1 : -1;
            var x = row1[field], y = row2[field];
            var result = (x < y ? -1 : (x > y ? 1 : 0)) * sign;
            if (result != 0) {
                return result;
            }
        }
        return 0;
    }, true);
}
grid.onSort.subscribe(函数(e,args){
网格分类器(args.sortCols,dataView);
});
功能网格分类器(sortCols、dataview){
排序(函数(第1行,第2行){
for(var i=0,l=sortCols.length;iy?1:0))*符号;
如果(结果!=0){
返回结果;
}
}
返回0;
},对);
}

以防万一,它会帮助别人。

谢谢@tin。这似乎是我需要的。但是,如果我想实现排序/过滤,我可以只使用网格进行排序,还是需要使用DataView?我只使用网格显示,但是实现DataView似乎需要我做更多的工作。网格不会处理数据。是的。也就是说,您不必使用DataView进行排序。只需对数据进行排序并使网格无效,以反映数据中的更改。比如:myData.sort(combinedComparer),我现在正在努力解决同一个问题。我需要多列排序和筛选,但我还没有实现DataView。DataView似乎只进行单列排序,但可能有一种方法可以替代它。@Fantius-您不需要使用DataView进行排序。只需直接对数据进行排序,然后使用grid.invalidate()使网格无效。