【问题标题】:JQuery jqgrid not sorting on client sideJQuery jqgrid不在客户端排序
【发布时间】:2013-05-04 20:14:19
【问题描述】:

数据可以正常加载到网格中,但不会排序。

当我单击表头时,会出现排序箭头,但数据没有被排序。

谢谢。

    $("#CompTable").jqGrid({ 
            url:'BomExplosionInJsonObj.asp'
        ,   datatype: 'json'
        ,   mtype: 'GET'
        ,   height: 400
        ,   colNames:['Part','Description','Src','Std Usage','Usage Inc Scrap','Rate Scrap','UOM','Item','Unit Cost','Stock']
        ,   colModel:[  {name:'COMP1_PART',index:'Part', width:120}
                                ,   {name:'WSCOMPDESC',index:'Desc', width:300}
                                ,   {name:'WSCOMPSRC',index:'Src', width:10}
                                ,   {name:'COMPUSAGE',index:'Usage', width:80, align:"right",sorttype:"float"}
                                ,   {name:'WSGROSSQTY',index:'TotUsage', width:80, align:"right",sorttype:"float"}
                                ,   {name:'COMPRATE_SCRAP',index:'Rate Scrap', width:80, align:"right",sorttype:"float"}
                                ,   {name:'COMPBASIC_UNIT',index:'UOM', width:20}
                                ,   {name:'COMP1_ITEM',index:'Item', width:20}
                                ,   {name:'WSCOMPUNITCOST',index:'UnitCost', width:80, align:"right",sorttype:"float"}
                                ,   {name:'WSCOMPQTYSTOCK',index:'Stock', width:80, align:"right",sorttype:"float"}
                            ]
        ,   jsonReader: {
                root:"rows"
            ,   page: "page"
            ,   total: "total"
            ,   records: "records"
            ,   repeatitems: false
            ,   id: "0"
            }
        ,   multiselect: false
        ,   caption: "Bom Detail"
        ,   rowNum: 10000
        ,   autoencode: true
        ,   loadonce: true
        ,   sortable: true
        ,   loadComplete: function() {jQuery("#CompTable").trigger("reloadGrid");}// Call to fix client-side sorting
    });
});

返回的 JSON 数据(从 firebug 读取)。

    {
     "total":"1"
    ,"page":"1"
    ,"records":"2"
    , "rows":
      [
       {"ID":1,"WSCOMPDESC":"ZYTEL E101L BLK MOUL ","WSCOMPUNITCOST":7.08,"WSCOMPSRC":"P ","WSCOMPQTYSTOCK":75,"COMPBASIC_UNIT":"KG ","COMPUSAGE":0.0034,"COMPRATE_SCRAP":0,"WSGROSSQTY":0.0034,"COMP1_PART":"1180019 ","COMP1_ITEM":" "
       },
       {"ID":2,"WSCOMPDESC":"INSERT ","WSCOMPUNITCOST":1.89,"WSCOMPSRC":"P ","WSCOMPQTYSTOCK":400,"COMPBASIC_UNIT":"EA ","COMPUSAGE":2,"COMPRATE_SCRAP":0,"WSGROSSQTY":2,"COMP1_PART":"4OWE195689\/ISS 2 ","COMP1_ITEM":" "
       }
      ]
    }

【问题讨论】:

    标签: jquery jqgrid


    【解决方案1】:

    你的代码有很多重要的错误:

    1. colModel 包含 index 属性,这些属性与同一项目的 name 的值不同。这是主要的错误。您没有指定 jqGrid 的任何 sortname 选项,因此服务器永远不会看到 index 属性的值。如果您使用loadonce: true,那么index 属性必须与name 属性的值相同。 我建议您根本不要包含 index 属性。在这种情况下,index 属性将使用name 属性的值进行初始化
    2. 您在 jsonReader: id: "0" 中使用了错误的 id 属性值。在repeatitems: true 的情况下,有时会使用这样的值。在这种情况下,该行将在 JSON 输入中表示为 array。所以0 值将是正确的,因为 in 可以用作数组中的索引。在使用repeatitems: false 的情况下,JSON 输入中表示数据行的项目是具有命名属性的对象。所以你应该在你的情况下使用 id: "ID" 。此外,您不需要在jsonReader 中包含默认值的属性(root:"rows"page: "page")等等。
    3. 下一个问题是在loadComplete 内部使用无条件的reloadGrid。您应该了解loadComplete 将在每次重新加载网格时执行(本地重新加载事件)。所以永久重新加载网格是错误的。此外,从另一个角度来看,在loadComplete 内部使用reloadGrid 是不好的。如果您触发reloadGrid,该事件将立即执行*,但网格不在处理先前的加载。因此,在setTimeout 内部以50 ms 之类的小时间间隔触发重新加载会更正确。
    4. 最后的建议是使用K&R(Kernighan 和 Ritchie 的)编写代码风格。您在另一种计算机语言中使用哪种格式的代码格式并不重要,您个人认为哪种格式最好读也不重要。 JavaScript 有它自己的权利。其中之一是自动分号插入(例如,参见here)。如果您遵循 K&R,您将永远不会遇到自动分号插入的任何问题。
    5. 如果您不需要显示太多行,我建议您使用height: "auto",并使用可以减少代码大小并简化其管理的列模板。

    经过上述更改后,可能会如下所示

    var myFloatTemplate = { width: 80, align: "right", sorttype: "float" };
    
    $("#CompTable").jqGrid({
        url: "BomExplosionInJsonObj.asp",
        datatype: "json",
        height: "auto",
        colNames: ["Part", "Description", "Src", "Std Usage", "Usage Inc Scrap", "Rate Scrap", "UOM", "Item", "Unit Cost", "Stock"],
        colModel: [
            {name: "COMP1_PART", width: 120},
            {name: "WSCOMPDESC", width: 300},
            {name: "WSCOMPSRC", width: 40},
            {name: "COMPUSAGE", template: myFloatTemplate},
            {name: "WSGROSSQTY", width: 120, template: myFloatTemplate},
            {name: "COMPRATE_SCRAP", width: 90, template: myFloatTemplate},
            {name: "COMPBASIC_UNIT", width: 60},
            {name: "COMP1_ITEM", width: 60},
            {name: "WSCOMPUNITCOST", template: myFloatTemplate},
            {name: "WSCOMPQTYSTOCK", template: myFloatTemplate}
        ],
        jsonReader: {
            repeatitems: false,
            id: "ID"
        },
        caption: "Bom Detail",
        rowNum: 10000,
        autoencode: true,
        loadonce: true,
        sortable: true,
        sortname: "COMP1_PART",
        //sortorder: "desc",
        loadComplete: function () {
            var $self = $(this);
            if ($self.jqGrid("getGridParam", "datatype") === "json") {
                setTimeout(function () {
                    $self.trigger("reloadGrid"); // Call to fix client-side sorting
                }, 50);
            }
        }
    });
    

    对应的demo是here。本地排序有效,它显示以下结果

    更新:从我开发的 jqGrid 的 4.12.0 free jqGrid fork 版本开始,支持新的 forceClientSorting: true 选项。它与loadonce: true 选项结合使用,允许首先从服务器响应加载所有数据,然后对数据进行本地排序,然后才显示数据页面。它通过在setTimeout 中重新加载网格来实现技巧,从loadComplete 开始,在答案中描述,不需要。只需将上面的loadComplete 代码替换为一个附加选项forceClientSorting: true。选项forceClientSorting: true 有另外两个好处:

    1. 在显示第一个(未排序的)网格后看不到任何闪烁;
    2. 网格的性能更好,尤其是当它有很多行时,因为显示网格的速度比排序慢得多。此外,旧答案中描述的技巧显示网格,然后删除内容(也很慢),然后再次显示排序的网格。

    【讨论】:

    • 这是一个很好的答案 - 谢谢。 reloadgrid 是我在另一个关于客户端排序的 stackoverflow 调用中发现的。刚开始使用 jqgrid,所以试图了解它是如何工作的。感谢您的帮助。
    【解决方案2】:

    您发布的代码显示排序将在服务器而不是客户端上完成。您的 jqGrid 将发布 sordsidx 参数以允许您在将数据返回到 jqGrid 时执行此操作。

    例如:C# MVC 控制器代码,其中也执行分页

    public ActionResult GetGridData(string sidx, string sord, int page, int rows, bool _search, string filters)
    {
     ...
     var pagedQuery = wholeDataSet.OrderBy(sidx + " " + sord).Skip((page - 1) * rows).Take(rows).ToList();
     ...
    

    【讨论】:

      【解决方案3】:

      浏览了几个答案并尝试了大多数选项,但在本地完美运行的代码仍然无法在部署中运行。 最后,我删除了 dotnetcdn 和 googleapis 的 jquery 链接,并开始了解基础 -

      https://jqueryui.com/sortable/ 上开放源代码 并复制了 src 链接

      <script src="https://code.jquery.com/jquery-1.12.4.js"></script> 
      <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
      

      我已经 68 岁了,三天的奋斗实在是太过分了。 所以在stackoverflow上分享答案 这是我对所有帮助我学习编码的人的回报

      【讨论】:

        猜你喜欢
        • 2011-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-09
        • 1970-01-01
        • 2011-03-12
        • 1970-01-01
        • 2012-02-20
        相关资源
        最近更新 更多