免费的 jqgrid 自定义格式化程序在排序或过滤后丢失

free jqgrid custom formatter lost after sorting or filtering

我正在使用免费的 jqgrid 4.13.0

我写了一个自定义格式化程序,但不幸的是,在 table 排序或过滤后,我那列的单元格内容总是丢失。我可能在格式化程序函数中做错了什么,但还没有真正理解缺少的东西。任何人都可以发现我的错误吗?为什么内置的可以正常工作,但我的却不行。我受到了这个启发:http://www.ok-soft-gmbh.com/jqGrid/CascadingFormater.htm

我可以看到示例是如何调用 $.fn.fmatter.call 的,也许我也需要这样做。这是关键吗?不幸的是,如果我自己编写函数,我找不到任何关于如何执行此操作的文档。

这是我的设置:

var formatEnduser = function (cellValue, options, rowObject, action){
    return rowObject.so_enduser_id == undefined ? '' : '<a href="index.php?module=Accounts&view=Detail&record='+rowObject.so_enduser_id+'">'+rowObject.so_enduser_name+'</a>';
}

$("#jqGrid").jqGrid({
    datatype: "jsonstring",
    datastr: jsonData,
    jsonReader: {
        root: 'rows',
        id: 'crmentity_id',
        repeatitems: false,
        page:  function(obj) { return 1; },
        total: function(obj) { return 1; },
        records: function(obj) { return obj.rows.length; },
    },
    autowidth: true,
    height: 600,
    shrinkToFit: true,
    rownumbers: true,
    rowNum: 5,
    pager: false,
    loadonce: true,
    viewrecords: true,
    colModel: [
        {
            name: 'crmentity_id',
            key: true,
            hidden: true
        },
        {
            label: 'Enduser',
            name: 'so_enduser_name',
            searchoptions: {
                sopt : ['cn']
            },
            formatter: formatEnduser
        },
    ]
});
$('#jqGrid').jqGrid('filterToolbar');

对象 jsonData 如下所示:

Object { rows=[623],  so_total_total=4321, in_total_total=1234 }

在属性rows中可以找到这个:

[Object { crmentity_id="60199",  so_enduser_id="6808",  so_enduser_name="enduser123",  mehr...}, Object { crmentity_id="60136",  so_enduser_id="6362",  so_enduser_name="userend321",  mehr...}, 620 mehr...]

非常感谢您的帮助!

编辑:我添加了一个 jsfiddle 来演示问题,在过滤器中搜索 end 并查看数据如何消失。排序也是一样的。 http://jsfiddle.net/tztj9yn7/2/

主要问题是您的代码如下。您使用 datatype: "jsonstring" 并且自定义格式化程序使用输入数据的 属性 so_enduser_id,但 属性 不是网格的列。数据类型 "jsonstring" 将以与数据类型 "json"(或 "jsonp" 或 "xml")相同的方式处理。它将由 jqGrid 读取并仅在本地保存来自 colModeljsonReader.id 的列。因此,输入数据的 属性 so_enduser_id 将在 rowObject 中仅在初始读取网格 期间可用。到目前为止,我写的所有内容对于旧的 jqGrid 和免费的 jqGrid 都是一样的。

在使用 old jqGrid 的情况下,有两种替代方法可以解决问题:

  • 添加隐藏列 name: "so_enduser_id"
  • datatype: "jsonstring", datastr: jsonData替换为datatype: "local", data: jsonData.rows并将jsonReader替换为localReader: { id: 'crmentity_id' }。输入数据将与所有属性一起保存(就像在输入中一样)以防使用datatype: "local",问题将得到解决。

如果您需要直接从 URL 加载数据,则第二种方法 (datatype: "local") 将不可行,唯一的方法是对所有属性使用隐藏列您稍后需要。

免费的 jqGrid 为您提供了另一种非常简单的方法:使用 additionalProperties 选项。 additionalProperties 的思路很简单。有时需要从每一项输入数据中保存一些 附加属性 以便稍后在本地使用(因为 loadonce: true 的使用)。将数据保存在 DOM 中比将数据保存在 JavaScript 结构中要昂贵得多。可以只使用像 additionalProperties: ["crmentity_id", "so_enduser_id"] 这样的选项来通知免费的 jqGrid 读取一些其他属性并保存在本地。因此,您的代码将立即得到修复:请参阅 http://jsfiddle.net/tztj9yn7/3/

关于在免费 jqGrid 中使用自定义格式化程序的另一个重要建议。 rowObject 参数存在一些重要问题。它只是 输入项 与源代码中的完全一样。因此,如果您使用 datatype: "xml" 为例,那么 rowObject 参数将是 XML 节点。同样,如果您要使用 repeatitems: true 格式(["60199", "6808", "enduser123"] 而不是 {crmentity_id:"60199", so_enduser_id:"6808", so_enduser_name:"enduser123"}),那么您将不得不使用 rowObject[1] 而不是 rowObject.so_enduser_id 来访问属性 so_enduser_id 来自 初始 输入数据。在下一次排序或过滤时,您将得到 rowObject (rowObject.so_enduser_id) 的 另一种格式,因为输入数据将是来自本地 data 范围。免费的jqGrid仍然使用相同格式的rowObject参数来提供与旧版本jqGrid的最佳兼容性,但它额外设置了rowData属性 options 参数。 options.rowData 具有 always 确定的数据命名格式,并且可以始终使用 options.rowData.so_enduser_id 独立于输入数据的格式和所使用的 datatype 。因此 options.rowData 是访问输入数据 的首选方式。根本不应该使用第三个参数。格式化程序的结果代码将是

var formatEnduser = function (cellValue, options) {
        var item = options.rowData;

        return item.so_enduser_id == undefined ?
                '' :
                '<a href="index.php?module=Accounts&view=Detail&record=' +
                    item.so_enduser_id + '">' + item.so_enduser_name + '</a>';
};

http://jsfiddle.net/tztj9yn7/4/