jQuery jqgrid不在客户端排序 [英] JQuery jqgrid not sorting on client side
问题描述
数据可以很好地加载到网格中,但不会排序.
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:
-
colModel
包含的index
属性不同于同一项目的name
值.这是主要的错误.您没有指定jqGrid的任何sortname
选项,因此服务器将永远不会看到index
属性的值.如果使用loadonce: true
,则index
属性必须与name
属性的值相同. 我建议您完全不包含index
属性.如果index
属性将使用name
属性的值初始化 - 您在
jsonReader
:id: "0"
中使用了错误的id
属性值.在repeatitems: true
的情况下,有时会使用这样的值.在这种情况下,该行将在JSON输入中表示为 array .因此0
值将是正确的,因为in可用作数组中的索引.在使用repeatitems: false
的情况下,JSON输入中表示数据行的项目是具有命名属性的对象.因此,在您的情况下,应使用id: "ID"
.此外,您不需要在jsonReader
中包括默认值为属性的属性(root:"rows"
,page: "page"
),等等. - 下一个问题是在
loadComplete
内部使用无条件的reloadGrid
.您应该了解,loadComplete
将在每次网格重新加载时执行 (本地重新加载事件).因此,永久重新加载网格是错误的.另外,从另外的观点出发,在loadComplete
内部使用reloadGrid
是不好的.如果触发reloadGrid
,则事件将立即*立即执行,但是网格未在处理先前的加载.因此,以较小的时间间隔(例如50
ms)触发setTimeout
内部重新加载会更正确. - 最后一个建议是使用 K& R (Kernighan和Ritchie的)的代码编写风格.在另一种计算机语言中使用哪种格式的代码格式并不重要,您个人认为哪种格式最容易阅读也不重要. JavaScript拥有自己的权利.一种是自动插入分号(请参见此处)例子).如果您遵循K& R,则自动分号插入将永远不会有任何问题.
- 如果您不需要显示太多的行并使用列模板,那么我建议您使用
height: "auto"
.这可以减少代码的大小并简化代码的管理.
colModel
containsindex
properties which are different from the value ofname
for the same item. It's the main bug. You don't specified anysortname
option of jqGrid so the values ofindex
properties will be never seen by the server. If you useloadonce: true
thenindex
properties must be the same as the values ofname
properties. I recommend you don't includeindex
properties at all. In the caseindex
properties will be initialized with the values ofname
properties- You use wrong value of
id
property injsonReader
:id: "0"
. One use such value sometime in case ofrepeatitems: true
. In the case the row will be represented in JSON input as array. So0
value will be correct because in can be used as index in the array. In case of usagerepeatitems: false
the items represented rows of data in the JSON input are objects with named properties. So You should useid: "ID"
in your case. Moreover you don't need to include injsonReader
the properties which value are default (root:"rows"
,page: "page"
) and so on. - The next problem is the usage of unconditional
reloadGrid
inside ofloadComplete
. You should understand thatloadComplete
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 ofreloadGrid
inside ofloadComplete
is bad from another point of view. If you triggerreloadGrid
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 ofsetTimeout
with some small time interval like50
ms. - 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.
- 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:
- 在显示第一个(未排序的)网格后,看不到任何闪烁;
- 网格的性能更好,尤其是在有很多行的情况下,因为显示网格的速度要慢于排序.此外,旧答案中描述的技巧将显示网格,然后删除内容(速度也很慢),然后再次显示排序后的网格.
这篇关于jQuery jqgrid不在客户端排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!