格式化程序在排序或搜索后给出不正确的结果

Formatters give incorrect result after sort or search

我有以下使用 free-jqgrid 的代码。它第一次正确加载(状态为“活动”,合作伙伴?为“是”)。但是当我进行排序或搜索时,值变得不正确(Status 是“Retired”,Partner? 是“No”)。

为什么格式化程序给出了错误的值?如何解决这个问题?

脚本

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/start/jquery-ui.css" rel="stylesheet" />

    <script src="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.13.6/js/jquery.jqgrid.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.13.6/css/ui.jqgrid.min.css" rel="stylesheet" />

    <script type="text/javascript">


        function getCurrentPractice ()
        {
            return "Test";
        }

        function getGridCaption() {
            return "<div style='font-size:15px; font-weight:bold; display:inline; padding-left:10px;'><span class='glyphicon glyphicon-check' style='margin-right:3px;font-size:14px;'></span>" + getCurrentPractice() + " " + "</div>" +
            "<div style='float:right; padding-right:20px; padding-bottom:10px; display:inline;>" +
           "<div style='float:right;width:550px;  padding-bottom:20px;'>" +
                "<input type='text' class='form-control' id='filter' placeholder='Search'  style='width:250px; height:30px; float:right; ' />" +
            " </div>" +
            "</div>";
        }

        $(function () {

            var currentPractice = "P";
            var grid = $("#list2");
            grid.jqGrid({
                url: '/Home/GetProviders',
                datatype: "json",
                postData:
                {
                    practiceName: function () { return currentPractice }
                },

                colNames: [
                            'Practice',
                            'ProviderID',
                            'Partner?',
                            'Status'
                ],
                colModel: [
                    { name: 'Practice', hidden: false },
                    { name: 'ProviderID', hidden: false },
                    {
                        name: 'PartnerStatusText',
                        width: 70,
                        formatter: function (cellvalue, options, rowObject) {

                            var isPartner = rowObject.IsPartner;
                            return isPartner == true ? 'Yes' : 'No';
                        }
                    },
                    {
                        name: 'ActiveStatusText',
                        width: 70,
                        formatter: function (cellvalue, options, rowObject) {
                            var isActive = rowObject.IsActive;
                            return isActive == true ? 'Active' : 'Retired';
                        }
                    }
                ],
                ignoreCase: true,
                loadonce: true,
                rowNum: 25,
                rowList: [15, 25, 35, 50],
                pager: '#pager2',
                viewrecords: true,
                sortable: true,
                caption: getGridCaption(),

                beforeSelectRow: function (rowid, e) {
                    //Avoid selection of row
                    return false;
                },
                loadComplete: function () {

                }


            });
            grid.jqGrid('navGrid', '#pager2', { edit: false, add: false, del: false });

            //Filter Toolbar
            $("#advancedSearch").click(function () {
                grid.jqGrid('filterToolbar', { stringResult: true, searchOnEnter: false, defaultSearch: "cn" });
            });


            //Top Search
            $("#filter").on('keyup', function () {
                var searchFiler = $("#filter").val(), f;

                if (searchFiler.length === 0) {
                    grid[0].p.search = false;
                    $.extend(grid[0].p.postData, { filters: "" });
                }
                f = { groupOp: "OR", rules: [] };
                f.rules.push({ field: "Practice", op: "cn", data: searchFiler });
                grid[0].p.search = true;
                $.extend(grid[0].p.postData, { filters: JSON.stringify(f) });
                grid.trigger("reloadGrid", [{ page: 1, current: true }]);
            });


        });
    </script>

</head>

HTML

<div style="float:left; border:1px solid red;">
    <div id="divGrid" style="width: 680px; min-height: 50px; float: left; border: 1px solid silver;">
        <table id="list2"></table>
        <div id="pager2"></div>
    </div>
</div>

服务器代码

[AllowAnonymous]
public JsonResult GetProviders(string practiceName)
{

    //System.Threading.Thread.Sleep(3000);
    List<Provider> providers = new List<Provider>();
    Provider p = new Provider();
    p.Practice = "Test1";
    p.ProviderID = 1;
    p.IsActive = true;
    p.IsPartner = true;
    providers.Add(p);

    Provider p2 = new Provider();
    p2.Practice = "Test2";
    p2.ProviderID = 2;
    p2.IsActive = true;
    p2.IsPartner = true;
    providers.Add(p2);

    return Json(providers, JsonRequestBehavior.AllowGet);
}

更新

感谢 Oleg,可以在此处找到工作演示 - Fiddle。它使用 JSFiddle 的 "/echo/json/" 服务从服务器获取数据。

它使用 sorttypeadditionalProperties。这可以在没有 additionalProperties 的情况下重写 - 当我有机会重新访问它时我需要这样做。

问题看起来很简单。从服务器返回的数据包含属性 PracticeProviderIDIsActiveIsPartner。在初始加载期间,这些属性在 rowObject 中可用。您还使用 loadonce: true 选项。因此免费的 jqGrid 将尝试在本地保存一些数据,但是哪一个呢? jqGrid 默认保存对应列名称的属性:PracticeProviderIDPartnerStatusTextActiveStatusText,但 jqGrid 没有其他属性 IsActive 的信息IsPartner 也需要保存。

您可以通过两种替代方法解决问题:

  1. 您将列名称 PartnerStatusTextActiveStatusText 重命名为 IsActiveIsPartner
  2. 您添加选项 additionalProperties: ["IsActive", "IsPartner"] 以通知 jqGrid 在本地读取和保存附加属性。

此外,我建议您在自定义格式化程序中使用 options.rowData 而不是 rowObject。您可以跳过 3-d 参数并使用 formatter: function (cellvalue, options) {...}.

最后一句话:自定义格式化程序的当前代码非常简单。您需要将一些输入值(truefalse)替换为另一个文本。可以使用 formatter: "select" 的情况:

    colModel: [
        { name: "Practice" },
        { name: "ProviderID" },
        {
            name: "IsPartner",
            width: 70,
            formatter: "select",
            formatoptions: { value: "false:No;true:Yes" }
        },
        {
            name: "IsActive",
            width: 70,
            formatter: "select",
            formatoptions: { value: "false:Retired;true:Active" }
        }
    ],

https://jsfiddle.net/c9fge9yk/1/