jqgrid是一个比较好的开源表格编辑工具,最近在使用时碰到一个问题,通过调用jqGrid().trigger(‘reloadGrid’)实现数据排序时,出现页面卡顿,响应慢问题,后来使用jqery Dom操作将需要排序的表格行tr移到tbody最后实现。
页面截图:
处理标记为1的排在表格最后
页面只是实际项目的一个仿制页面,数据显示、按钮操作已经做了一些处理,原始操作如下:
1)这是个成品扫码出库页面;
2)每次扫码时,扫到的二维码表格行,会标记为已处理,并移到表格最后面;
3)实际操作中,当数据量超过200条的时候,扫描枪扫码后页面要等很久才能响应完,才能进行下个扫码操作。
当初代码实现
1)jgGrid构建时,默认flag升序排序:sortname: ‘flag’, sortorder: ‘asc’,
2)获取表格数据,jqGrid(“getRowData”),遍历找到二维码对应的行记录;
3)将该行记录, 已处理标记:flag设置为1;
4)调用jqGrid().trigger(‘reloadGrid’),会跟进flag进行重新排序,flag为1的都排在表格后面。
POC 页面代码
<html>
<head>
<meta charset="UTF-8" />
<title>jggrid大数据排序优化title>
<link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdn.bootcss.com/font-awesome/4.5.0/css/font-awesome.min.css" />
<link rel="stylesheet" href="https://cdn.bootcss.com/jqgrid/4.6.0/css/ui.jqgrid.css" />
<script src="https://cdn.bootcss.com/jquery/1.11.1/jquery.min.js">script>
<script src="https://cdn.bootcss.com/jqgrid/4.6.0/js/jquery.jqGrid.min.js">script>
head>
<body>
<div class="page-content">
<div class="page-head clearfix form-horizontal">
<div class="form-group form-group-sm form-group-np clearfix">
<button type="button" class="btn btn-sm btn-azure" onclick="setFlag()">设置已处理button>
<button type="button" class="btn btn-sm btn-azure" onclick="setAndReload()">设置已处理, jqGrid排序button>
<button type="button" class="btn btn-sm btn-azure" onclick="setAndDom()">设置已处理, jqDom操作排序button>
div>
div>
<div class="page-body">
<div class="panel panel-default" id="panel-orders">
<table id="orders">table>
div>
div>
div>
<script type="text/javascript">
var data = [];
function getBills() {
for (var i = 0; i < 1000; i ++) {
data.push({
sid: i,
bill_id: i,
bill_detail: i,
goods_id: i,
unit_id: i,
package_id: i,
ref_detail: i,
goods_no: 10000 + i,
goods_name: '零件名称' + 1000 + i,
car_type_name: '车型' + 1000 + i,
package_name: '包装器具' + 1000 + i,
unit_name: '单位',
snp: 0.89,
box_count: 1000 + i,
total_count: 1000 + i,
goods_count: 1000 + i,
out_count: 1000 + i,
bill_no: 'BN0000000' + i,
qrcode: '1000000000' + i,
barcode: '1000000000' + i,
flag: i >= 999 ? 1 : 0,
})
}
$("#orders").jqGrid("clearGridData").jqGrid('setGridParam',{data: data || []}).trigger('reloadGrid');
}
function setFlag() {
var rowIds = $("#orders").jqGrid("getGridParam", "selarrrow");
if(rowIds.length < 1) {
alert('请先选择行记录!'); return rowIds;
}
for (var i = 0, l = rowIds.length; i < l; i++) {
$("#orders").jqGrid("setCell", rowIds[i], 'flag', 1);
//
// $("#orders").jqGrid("setRowData", rowIds[i], 'flag', 1);
var rowData = $("#orders").jqGrid("getRowData", rowIds[i]);
rowData.flag = 1;
$("#orders").jqGrid("setRowData", rowIds[i], rowData);
}
$("#orders").jqGrid('resetSelection');
return rowIds;
}
function setAndReload() {
setFlag();
//
var stime = new Date();
$("#orders").jqGrid().trigger('reloadGrid');
console.log('sort time: ', new Date().getTime() - stime.getTime());
}
function setAndDom() {
var rowIds = setFlag();
//
var stime = new Date();
var $tbody = $("#orders tbody");
for (var i = 0, l = rowIds.length; i < l; i++) {
$("#" + rowIds[i]).appendTo($tbody);
}
console.log('sort time: ', new Date().getTime() - stime.getTime());
}
function flagFmt(data, type, row) {
return row.flag == "1" ? "Y" : "N";
}
$(function() {
$("#orders").jqGrid({
colModel: [
{label: "Y/N", name: null, width: 60, align:'center', formatter: flagFmt},
{label: "处理标记", name: "flag", width: 60, hidden:false},
{label: "零件号", name: "goods_no", width: 60},
{label: "零件名称", name: "goods_name", width: 180},
{label: "车型", name: "car_type_name", width: 70},
{label: "包装器具", name: "package_name", width: 70},
{label: "单位", name: "unit_name", width: 40},
{label: "装箱率", name: "snp", width: 50, sorttype: "number"},
{label: "箱数", name: "box_count", width: 40, sorttype: "number"},
{label: "需求总数", name: "total_count", width: 70, sorttype: "number"},
{label: "需求数量", name: "goods_count", width: 70,},
{label: "出库数量", name: "out_count", width: 70, sorttype: "number"},
{label: "订单号", name: "bill_no", width: 150},
{label: "二维码", name: "qrcode", width: 130},
{label: "条码", name: "barcode", width: 220}
],
datatype: 'local',
rownumbers: true,
multiselect: true,
sortname: 'flag',
sortorder: 'asc',
height: 500,
rowNum: 1000
});
getBills();
});
script>
body>
html>
2、页面操作描述
1)“设置已处理” 按钮,设置选中行的处理标记 = 1;
2)“设置已处理, jqGrid排序” 按钮,设置选中行的处理标记 = 1,并且调用jqGrid().trigger(‘reloadGrid’)进行数据排序,代码见setAndReload();
3)“设置已处理, jqDom操作排序” 按钮,设置选中行数据的处理标记 = 1,并且使用jquery进行dom操作,将处理标记 = 1的tr移到tbody最后,代码见setAndDom();
4)表格的Y/N列为处理标记的formatter列,处理标记 = 1显示绿底白字Y,否则显示白底黑字N
3、2种排序处理方式性能比较
数据行
reloadGrid排序 耗时(毫秒)
jquery dom操作 耗时(毫秒)
100
66
1
200
116
1
500
261
1
1000
412
2