jQuery jqgrid不在客户端排序 [英] JQuery jqgrid not sorting on client side

查看:51
本文介绍了jQuery jqgrid不在客户端排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

数据可以很好地加载到网格中,但不会排序.

The data loads fine into the grid, but it won't sort.

当我单击表标题时,将显示排序箭头,但未对数据进行排序.

When I click in the table header, the sort arrows appear, but the data's not being sorted.

谢谢.

    $("#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中读取).

JSON Data being returned (as read from 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":" "
       }
      ]
    }

推荐答案

您的代码有许多重要错误:

You code have many important errors:

  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,则事件将立即*立即执行,但是网格未在处理先前的加载.因此,以较小的时间间隔(例如50 ms)触发setTimeout内部重新加载会更正确.
  4. 最后一个建议是使用 K& R (Kernighan和Ritchie的)的代码编写风格.在另一种计算机语言中使用哪种格式的代码格式并不重要,您个人认为哪种格式最容易阅读也不重要. JavaScript拥有自己的权利.一种是自动插入分号(请参见此处)例子).如果您遵循K& R,则自动分号插入将永远不会有任何问题.
  5. 如果您不需要显示太多的行并使用列模板,那么我建议您使用height: "auto".这可以减少代码的大小并简化代码的管理.
  1. colModel contains index properties which are different from the value of name for the same item. It's the main bug. You don't specified any sortname option of jqGrid so the values of index properties will be never seen by the server. If you use loadonce: true then index properties must be the same as the values of name properties. I recommend you don't include index properties at all. In the case index properties will be initialized with the values of name properties
  2. You use wrong value of id property in jsonReader: id: "0". One use such value sometime in case of repeatitems: true. In the case the row will be represented in JSON input as array. So 0 value will be correct because in can be used as index in the array. In case of usage repeatitems: false the items represented rows of data in the JSON input are objects with named properties. So You should use id: "ID" in your case. Moreover you don't need to include in jsonReader the properties which value are default (root:"rows", page: "page") and so on.
  3. The next problem is the usage of unconditional reloadGrid inside of loadComplete. You should understand that loadComplete will be executed on every reloading of the grid (event on local reloading). So it would be wrong making permanent reloading of grid. Moreover usage of reloadGrid inside of loadComplete is bad from another point of view. If you trigger reloadGrid the event will be executed * immediately*, but the grid is not in processing of previous loading. So it would be more correct to trigger reloading inside of setTimeout with some small time interval like 50 ms.
  4. The last recommendation is usage of K&R (Kernighan and Ritchie's) style of writing of the code. It's not so important which style of formatting of the code you use in another computer language and it's not important which one you personally find the most nice to read. JavaScript has it's own rights. One from there is automatic semicolon insertion (see here for example). If you follow K&R you will never have any problems with automatic semicolon insertion.
  5. I recommend you to use height: "auto" if you need display not so much rows and use column templates which could reduce the size of your code and simplify its management.

在进行了上述说明之后,更改可能类似于以下内容

After described above changing the could will be something like below

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);
        }
    }
});

相应的演示位于此处.本地排序有效,并且显示以下结果

The corresponding demo is here. Local sorting works and it displays the following results

已更新:从4.12.0版开始免费jqGrid 我开发的jqGrid的fork支持新的forceClientSorting: true选项.它与loadonce: true选项结合使用,并允许首先从服务器响应中加载所有数据,然后对数据进行本地排序,然后才显示数据页面.它可以通过在loadComplete中重新加载网格(从loadComplete开始)来完成窍门,如答案所述,不需要.只需将上面的loadComplete代码替换为一个附加的选项forceClientSorting: true.选项forceClientSorting: true具有另外两个好处:

UPDATED: Starting with version 4.12.0 free jqGrid fork of jqGrid, which I develop, support new forceClientSorting: true option. It works in combination with loadonce: true option and allows first load all the data from the server response, then sort the data locally and only then to display page of the data. It makes the trick with reloading of grid inside of setTimeout, started in loadComplete, described in the answer, not needed. One need just replace the above loadComplete code to one additional option forceClientSorting: true. The option forceClientSorting: true have additional two benefits:

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

这篇关于jQuery jqgrid不在客户端排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆