Slickgrid - 自定义列排序器

6

我想知道是否可以更改列的数据类型。例如,传递给网格的json数据是字符串,但我希望slickgrid将其视为整数或浮点数,以便能够正确排序。

var data = [{"NOM": "Saguenay - Lac-Saint-Jean", "CODE": "02", "id": "0", "integer": "1"},]

我希望“integer”列是一个int类型而不是字符串,但不改变数据本身。
谢谢你的帮助。

我不熟悉Slickgrid,但从示例中可以看出,如果列数据具有数字类型,则它支持数字排序。因此,我认为您在这里唯一需要做的就是通过调用parseInt或parseFloat更改某些数据字段的数据类型。 - triclozan
你正在错误的方向上进行,这是需要考虑的类型...让我找到代码,我会给出答案。 - ghiscoding
2个回答

15

正如我在评论中提到的,你正在关注错误的地方(无意冒犯);实际上没有必要更改数据类型,因为这样做不会解决排序问题,因为SlickGrid默认排序是字符串排序。但是,您可以使用自定义排序来解决问题。

所以这里是解决方案:定义排序函数并根据需要使用它们。这里是您可以创建的自定义排序函数列表:

function sorterStringCompare(a, b) {
    var x = a[sortcol], y = b[sortcol];
    return sortdir * (x === y ? 0 : (x > y ? 1 : -1));
}
function sorterNumeric(a, b) {
    var x = (isNaN(a[sortcol]) || a[sortcol] === "" || a[sortcol] === null) ? -99e+10 : parseFloat(a[sortcol]);
    var y = (isNaN(b[sortcol]) || b[sortcol] === "" || b[sortcol] === null) ? -99e+10 : parseFloat(b[sortcol]);
    return sortdir * (x === y ? 0 : (x > y ? 1 : -1));
}
function sorterRating(a, b) {
    var xrow = a[sortcol], yrow = b[sortcol];
    var x = xrow[3], y = yrow[3];
    return sortdir * (x === y ? 0 : (x > y ? 1 : -1));
}
function sorterDateIso(a, b) {
    var regex_a = new RegExp("^((19[1-9][1-9])|([2][01][0-9]))\\d-([0]\\d|[1][0-2])-([0-2]\\d|[3][0-1])(\\s([0]\\d|[1][0-2])(\\:[0-5]\\d){1,2}(\\:[0-5]\\d){1,2})?$", "gi");
    var regex_b = new RegExp("^((19[1-9][1-9])|([2][01][0-9]))\\d-([0]\\d|[1][0-2])-([0-2]\\d|[3][0-1])(\\s([0]\\d|[1][0-2])(\\:[0-5]\\d){1,2}(\\:[0-5]\\d){1,2})?$", "gi");

    if (regex_a.test(a[sortcol]) && regex_b.test(b[sortcol])) {
        var date_a = new Date(a[sortcol]);
        var date_b = new Date(b[sortcol]);
        var diff = date_a.getTime() - date_b.getTime();
        return sortdir * (diff === 0 ? 0 : (date_a > date_b ? 1 : -1));
    }
    else {
        var x = a[sortcol], y = b[sortcol];
        return sortdir * (x === y ? 0 : (x > y ? 1 : -1));
    }
}

然后,在您的列定义中,您将使用任何自定义过滤器,而在您的情况下,sorterNumeric() 是您需要的...因此,您的列定义将如下所示(在末尾是自定义过滤器):

var columns = [                    
    {id:"column1", name:"column1", field: "Column String", width:40, sortable:true, sorter:sorterStringCompare},
    {id:"column2", name:"column2", field: "Column integer", width:40, sortable:true, sorter:sorterNumeric},
    {id:"column3", name:"column3", field: "Column rating", width:40, sortable:true, sorter:sorterRating}    
];

萨格奈...?魁北克人? :)

编辑
我忘记添加一段代码,将新的sorter属性附加到onSort事件(如果没有它,它当然不会起作用),请确保griddataView具有相同的对象名称,并更正为您的变量命名(如果需要),以下是代码:

grid.onSort.subscribe(function (e, args) {
  var cols = args.sortCols;

  dataView.sort(function (dataRow1, dataRow2) {
  for (var i = 0, l = cols.length; i < l; i++) {
      sortdir = cols[i].sortAsc ? 1 : -1;
      sortcol = cols[i].sortCol.field;

      var result = cols[i].sortCol.sorter(dataRow1, dataRow2); // sorter property from column definition comes in play here
      if (result != 0) {
        return result;
      }
    }
    return 0;
  });
  args.grid.invalidateAllRows();
  args.grid.render();
});

您也可以直接将代码放入最后的onSort.subscribe中,但我建议将排序器放入单独的函数中,因为这样更简洁(这就是我发送的代码)。


非常感谢!我现在明白了为什么在错误的地方搜索什么都找不到。是的,我是魁北克人 ;) - Below the Radar
你能提供这些代码的源码吗?也许我想对其他格式进行排序。 - Below the Radar
你需要哪种排序方式?如果需要,我还有一个针对ISO日期的排序方法...排序是一个简单的函数,你可以轻松地在谷歌上找到它,这不是SlickGrid的特殊功能... - ghiscoding
是的,我正在考虑对日期 ISO 进行排序。顺便问一下,由于您似乎是专家,是否有函数可以在编辑单元格时验证数据类型,这可以在 SlickGrid 中实现吗? - Below the Radar
1
我更新了我的代码,现在它也有日期ISO。顺便说一下,你只需要找出哪个比另一个大并返回0(相等),1(a > b)或-1(a < b),你可以通过谷歌搜索找到一堆排序...至于编辑器检查,是的,但这超出了本问题的范围...你应该发布另一个问题。 - ghiscoding
显示剩余4条评论

0

我用这个来正确排序数字。

grid.onSort.subscribe(function(e, args) {
    var cols = args.sortCols;

    data.sort(function(dataRow1, dataRow2) {
        for (var i = 0, l = cols.length; i < l; i++) {
            var result = sortOnString(cols, i, dataRow1, dataRow2);
            if (result != 0) {
                return result;
            }
        }
        return 0;
    });
    grid.invalidate();
    grid.render();
});

function sortOnString(cols, i, dataRow1, dataRow2) {
    var field = cols[i].sortCol.field;
    var sign = cols[i].sortAsc ? 1 : -1;
    console.log("name filed " + field);

    if (field === 'Folio' || field === 'Orden') {
        var value1 = parseInt(dataRow1[field]),
            value2 = parseInt(dataRow2[field]);
        console.log("name value 1 " + value1 + "name value 2 " + value2);
    } else {
        var value1 = dataRow1[field],
            value2 = dataRow2[field];
    }
    var result = (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign;
    return result;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接