【问题标题】:Sorting Slickgrid by Multiple Columns?按多列对 Slickgrid 进行排序?
【发布时间】:2011-06-23 20:34:44
【问题描述】:

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

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

【问题讨论】:

    标签: javascript jquery sorting slickgrid


    【解决方案1】:

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

    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 中反映排序顺序,虽然您不能直接这样做,但您可以通过在排序依据的列定义上设置“headerCssClass”并让它们显示箭头(或但是,您正在指示排序列)。

    【讨论】:

    • 谢谢@tin。这似乎是我需要的。但是我可以只使用网格进行排序,还是如果我想实现排序/过滤,是否需要使用 DataView?我只用网格显示它,但实现 DataView 似乎需要我做更多的工作。
    • 网格不会操纵您的数据。你做。话虽如此,您不必使用 DataView 进行排序。只需对数据进行排序并使网格无效以反映数据中的更改。如:myData.sort(combinedComparer)
    • 我现在正在努力解决同样的问题。我需要多列排序和过滤,但我还没有实现DataView。 DataView 似乎只进行单列排序,但可能有一种方法可以覆盖它。
    • @Fantius - 您不需要使用 DataView 进行排序。只需直接对数据进行排序并使用 grid.invalidate() 使网格无效。
    【解决方案2】:

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

    http://mleibman.github.com/SlickGrid/examples/example-multi-column-sort.html

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

    [编辑] 为了使它工作,我需要在单击列标题之前按住 shift (恕我直言,不是很直观) 另见:https://github.com/mleibman/SlickGrid/pull/276

    【讨论】:

      【解决方案3】:

      我花了一段时间试图用 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();      
      });
      

      记住所有以前的命令。只是工作。按预期工作。

      【讨论】:

        【解决方案4】:

        我让它在 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);
        }
        

        以防万一它对某人有所帮助。

        【讨论】:

          猜你喜欢
          • 2012-09-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多