在jqgrid中优化动态创建的colmodel [英] Optimize the dynamically created colmodel in jqgrid
问题描述
我正在研究动态绑定的jqgrid.我已经获得了所需的输出.但是我写了一个很大的代码,这影响了我的性能,而且不可读.
I'm working on the jqgrid which gets bound dynamically. I have got the required output. But i wrote a big code which affects my performance and its not readable.
我需要一个可以研究这个问题并简单地优化我的代码的人.
I need someone who can look into this and optimize my code simple.
谢谢.
我在我的工作代码中转载了此处
I have reproduced in my working code here
$.each($.parseJSON(columnsData).Table1, function () {
// debugger;
//Push the column name.
colHeader.push(this.Name);
//Check the datatype of the column.
switch (this.Datatype) {
case 'number':
if (this.DefaultValue != null && this.DefaultValue != "") {
// debugger;
colname.push({
name: this.Name, index: this.Name, width: 100, align: 'left', formatter: 'number', sortable: true, editable: false, sorttype: 'int', hidden: JSON.parse(this.IsHidden), editoptions: {
defaultValue: this.DefaultValue
}, editrules: { required: JSON.parse(this.IsRequired) }
});
}
else {
colname.push({
name: this.Name, index: this.Name, width: 100, align: 'left', formatter: 'number', sortable: true, editable: false, sorttype: 'int', hidden: JSON.parse(this.IsHidden), editrules: { required: JSON.parse(this.IsRequired) }
});
}
lastFieldName = this.Name.toString(); //Store the fieldName.
break;
case 'DateTime':
if (this.DefaultValue != null && this.DefaultValue != "") {
//If datetime then enable datepicker in the filter and edit form.
colname.push({
name: this.Name, search: true, index: this.Name, width: 100, stype: "text", editable: true, hidden: JSON.parse(this.IsHidden), searchoptions: {
dataInit: function (el) {
$(el).datepicker({
dateFormat: 'm/d/yy', maxDate: 0, changeMonth: true, changeYear: true, onSelect: function (dateText, inst) {
setTimeout(function () {
$('#TransactionsGrid')[0].triggerToolbar();
}, 50);
}
});
}
}, editoptions: {
dataInit: function (el) {
$(el).datepicker({
dateFormat: 'm/d/yy', maxDate: 0, changeMonth: true, changeYear: true
});
}, defaultValue: this.DefaultValue, readonly: 'readonly'
}, editrules: { required: JSON.parse(this.IsRequired) }
});
}
else {
colname.push({
name: this.Name, search: true, index: this.Name, width: 100, stype: "text", editable: true, hidden: JSON.parse(this.IsHidden), searchoptions: {
dataInit: function (el) {
$(el).datepicker({
dateFormat: 'm/d/yy', maxDate: 0, changeMonth: true, changeYear: true, onSelect: function (dateText, inst) {
setTimeout(function () {
$('#TransactionsGrid')[0].triggerToolbar();
}, 50);
}
});
}
}, editoptions: {
dataInit: function (el) {
$(el).datepicker({
dateFormat: 'm/d/yy', maxDate: 0, changeMonth: true, changeYear: true
});
}
}, editrules: { required: JSON.parse(this.IsRequired) }
});
}
lastFieldName = this.Name.toString();
break;
case 'dropdown':
if (this.DefaultValue != null && this.DefaultValue != "") {
// debugger;
if (this.ValueType == "F") {
colname.push({
name: this.Name, index: this.Name, width: 100, edittype: "select", editable: true, hidden: JSON.parse(this.IsHidden),
//formatter: imageFormatter, unformat: imageUnFormat,
/*(Set tooltip of the gridcell)
cellattr: function (rowId, val, rawObject, cm, rdata) {
if (rawObject[cm.name + "_Title"] == "") {
return 'title="' + rawObject[cm.name] + '"';
}
else
return 'title="' + val + ' (' + rawObject[cm.name + "_Title"] + ')"';
},*/
//IF dropdown then bind the values during edit form.
editoptions: { value: ':Select;' + this.ValueList.slice(0, -1), defaultValue: this.DefaultValue }, editrules: { required: JSON.parse(this.IsRequired) }, stype: 'select'
, searchoptions: { value: ':All;' + this.ValueList.slice(0, -1) }, align: 'left', sortable: true
});
}
else {
colname.push({
name: this.Name, index: this.Name, width: 100, edittype: "select", label: this.ValueId, hidden: JSON.parse(this.IsHidden),
//IF dropdown then bind the values during edit form.
editoptions: { value: ':Select;' + this.ValueList.slice(0, -1), defaultValue: this.DefaultValue }, editrules: { required: JSON.parse(this.IsRequired) }, stype: 'select'
, searchoptions: { value: ':All;' + this.ValueList.slice(0, -1) }, align: 'left', sortable: true
});
}
}
else {
if (this.ValueType == "F") {
colname.push({
name: this.Name, index: this.Name, width: 100, edittype: "select", editable: true, hidden: JSON.parse(this.IsHidden),
//IF dropdown then bind the values during edit form.
editoptions: { value: ':Select;' + this.ValueList.slice(0, -1) }, editrules: { required: JSON.parse(this.IsRequired) }, stype: 'select'
, searchoptions: { value: ':All;' + this.ValueList.slice(0, -1) }, align: 'left', sortable: true
});
}
else {
colname.push({
name: this.Name, index: this.Name, width: 100, edittype: "select", label: this.ValueId, hidden: JSON.parse(this.IsHidden),
//IF dropdown then bind the values during edit form.
editoptions: { value: ':Select;' + this.ValueList.slice(0, -1) }, editrules: { required: JSON.parse(this.IsRequired) }, stype: 'select'
, searchoptions: { value: ':All;' + this.ValueList.slice(0, -1) }, align: 'left', sortable: true
});
}
}
break;
default:
if (this.DefaultValue != null && this.DefaultValue != "") {
colname.push({
name: this.Name, index: this.Name, width: 100, align: 'left', sortable: true, editable: true, hidden: JSON.parse(this.IsHidden), editrules: { required: JSON.parse(this.IsRequired) }
});
}
else {
colname.push({
name: this.Name, index: this.Name, width: 100, align: 'left', sortable: true, editable: true, hidden: JSON.parse(this.IsHidden), editrules: { required: JSON.parse(this.IsRequired) }
});
}
break;
}
});
jQuery("#TransactionsGrid").jqGrid({
data: $.parseJSON(gridData).BuildTransactionsDataTable,
datatype: "local",
hoverrows: false,
colNames: colHeader,
colModel: colname,
id: 'TransactionId',
rowNum: 10,
rownumbers: true,
sortname: '_id',
viewrecords: true,
sortorder: 'desc',
caption: "Transaction Details",
height: '250px',
gridview: true,
ignoreCase: true
});
由于代码太大而无法查看,所以我做了小提琴.请调查一下
Since the code is too large to view, i have made the fiddle. Kindly look into that
已更新:
我必须在控制器中处理的情况,当在client(this.DataType
)端使用相同的情况时,代码将是一个大问题.
The cases i have to handle in my controller and when used the same in client(this.DataType
) side the code will be a big one.
//代码:
case FieldStyleModel.FieldType.Date:
case FieldStyleModel.FieldType.DropDownCalendar:
case FieldStyleModel.FieldType.DateWithoutDropDown:
case FieldStyleModel.FieldType.DateWithSpin:
drColumnDetails["Datatype"] = "date";
break;
case FieldStyleModel.FieldType.DateTime:
case FieldStyleModel.FieldType.DateTimeWithoutDropDown:
case FieldStyleModel.FieldType.DateTimeWithSpin:
drColumnDetails["Datatype"] = "datetime";
break;
case FieldStyleModel.FieldType.DropDown:
case FieldStyleModel.FieldType.DropDownList:
case FieldStyleModel.FieldType.DropDownValidate:
drColumnDetails["Datatype"] = "dropdown";
break;
case FieldStyleModel.FieldType.URL:
drColumnDetails["Datatype"] = "hyperlink";
break;
case FieldStyleModel.FieldType.IntegerNonNegative:
case FieldStyleModel.FieldType.IntegerNonNegativeWithSpin:
case FieldStyleModel.FieldType.IntegerPositive:
case FieldStyleModel.FieldType.IntegerPositiveWithSpin:
drColumnDetails["Datatype"] = "number";
break;
case FieldStyleModel.FieldType.Integer:
case FieldStyleModel.FieldType.IntegerWithSpin:
drColumnDetails["Datatype"] = "integer";
break;
case FieldStyleModel.FieldType.Time:
case FieldStyleModel.FieldType.TimeWithSpin:
case FieldStyleModel.FieldType.TimeZone:
drColumnDetails["Datatype"] = "Time";
break;
case FieldStyleModel.FieldType.CheckBox:
drColumnDetails["Datatype"] = "checkbox";
break;
default:
drColumnDetails["Datatype"] = "string";
break;
推荐答案
小注释:
- 参数
height
的值可以使用诸如height: 250
或字符串"auto"
或"100%"
之类的数字.值'250px'
不正确.我对height
的偏爱值是"auto"
. - 您应该删除jqGrid的未知
id
选项(请参见代码中的id: 'TransactionId'
). - 怀疑值
sortname: '_id'
.您真的在输入数据的每一项中都有_id
属性吗? - 如果输入数据
$.parseJSON(gridData).BuildTransactionsDataTable
仅包含数据,应将其解释为文本而不是HTML片段,那么我建议您使用jqGrid的autoencode: true
选项,
- the value of parameter
height
can be wither a number likeheight: 250
or string"auto"
or"100%"
. The value'250px'
is incorrect. My favorit value forheight
is"auto"
. - you should remove unknown
id
option of jqGrid (seeid: 'TransactionId'
in your code). - the value
sortname: '_id'
is suspected. Do you really have_id
property in every items of the input data? - if the input data
$.parseJSON(gridData).BuildTransactionsDataTable
contains only the data should be interpreted as text and not as HTML fragments then I'd recommend you to useautoencode: true
option of jqGrid,
如果您在网格中加载了数千行数据,则答案中描述的技巧可以提高以下方面的性能:将数据加载到网格中.您只需要执行两个步骤:
If you load many thousand of rows of data in the grid then the trick described in the answer can improve performance of loading of data in the grid. You need just do two steps:
- 删除网格的
sortname
和sortorder
选项.大型数据集的排序可能需要一些时间.没有sortname
(或sortname: ""
)表示显示未排序数据.它将提高数据初始加载的性能. - 删除网格的
data
选项,并将其设置在onInitGrid
回调内部:
- Remove
sortname
andsortorder
options of the grid. Sorting of large dataset can take time. Nosortname
(orsortname: ""
) means displaying unsorted data. It will improve the performace of initial loading of data. - Remove
data
option of the grid and set it inside ofonInitGrid
callback instead:
$("#TransactionsGrid").jqGrid({
datatype: "local",
hoverrows: false,
colNames: colHeader,
colModel: colname,
rowNum: 10,
rownumbers: true,
viewrecords: true,
caption: "Transaction Details",
height: "auto",
gridview: true,
autoencode: true,
ignoreCase: true,
onInitGrid: function () {
// get reference to parameters
var p = $(this).jqGrid("getGridParam");
// set data parameter
p.data = $.parseJSON(gridData).BuildTransactionsDataTable;
}
});
演示来自演示),数据加载大约需要1600-11000毫秒.如果添加数据排序(请参见更多演示 ),那么我得到2100-29000毫秒之间的时间.
The demo from the answer loads 90000 rows of data and the loading takes about 52-130 ms depend on the web browser which I use. It's a good time in my opinion. Without the trick (see the demo) the loading of data takes about 1600-11000 ms. If one add sorting of the data (see one more demo) then I get the time between 2100-29000 ms.
已更新:首先,您应该从JavaScript代码中删除所有不需要的内容.
UPDATED: First of all you should remove from JavaScript code all unneeded things.
-
index
属性的必须必须与name
属性的值相同.如果删除index
属性,则jqGrid将在内部创建正确的index
值.因此,我强烈建议您不要在colModel
中指定所有index
属性. - 我建议您从
cmTemplate
中的colModel
项中移动所有常用属性(或最常用的属性).例如,如果您在colModel
的所有项目中使用width: 100
,则应删除该属性并添加jqGrid选项cmTemplate: { width: 100 }
,而不是将具有相同值的属性width
放置在该项目的 every 项目中colModel
. - 我建议您使用
colModel属性来检查表中 Default 列中的值?id = wiki:colmodel_options"rel =" nofollow noreferrer>文档.您会发现 align: 'left'
,editable: false
,sortable: true
,stype: "text"
和其他一些属性的放置不需要.我建议您删除属性. - 如果您有一些来自后端的数据的本机唯一ID,建议您使用yot作为行ID.有两个选项:1)您需要向用户显示该列.在这种情况下,您只需在
colModel
中添加key: true
属性即可.2)您无需向用户显示ID.在这种情况下,您不需要使用数据创建任何隐藏列.取而代之的是,您只需添加localReader: { id: "TransactionId" }
选项即可通知jqGrid从何处获取行ID.本地rowid的使用对于编辑特别实用.在编辑过程中,jqGrid将将具有rowid的id
参数发送到服务器.我建议您另外使用prmNames: { id: "TransactionId" }
.对于jqGrid,其名称为rowid为"TransactionId"
的属性,而不是编辑期间的默认名称"id"
. - 用
colModel
的name
属性值填充colNames
.您不需要这样做.在这种情况下,建议您完全不要指定colNames
选项.在这种情况下,jqGrid将用colModel
的label
属性值或如果label
不存在的name
属性值在内部填充colNames
. - 建议您隐藏所有数据项中为空的值(
null
,""
," "
等)的列.它使用户更易于阅读网格并提高了网格的性能.对于Web浏览器来说,显示许多列比显示许多行要贵得多.因此,隐藏不需要的列可以提高网格的性能. - 我还没有在演示中解决的另一个重要问题 如下.您使用错误的
name
属性值.您当前的代码包含具有name: "Employee Name"
或name: "Avg.Num Of Steps Occur"
的列.重要的是要了解,name
属性将用于构建某些内部jqGrid元素的id
属性,并将在选择器中使用. jQuery选择器不应包含任何元字符(!"#$%&'()*+,./:;<=>?@[\]^``{|}~
).另外,例如HTML 4的id
不能包含空格.请参见此处.我严格建议您在name
中仅使用字母([A-Za-z]),数字([0-9]),连字符(-")或下划线("_").第一个符号应该是字母.如果您不遵守规则,可能会遇到很多问题(排序,搜索等问题).可能应该设置label: this.Name
属性,并使用一些规则基于this.Name
建立正确的name
值.在编辑过程中,应将此属性包含在原始的this.Name
属性中,以使编辑结果的发送与固定name
属性之前的发送结果相同.
- The
index
properties must be the same as the value ofname
properties. If you removeindex
properties jqGrid internally will create correctindex
values. So I strictly recommend all don't specifyindex
properties incolModel
. - I recommend you to move all common properties (or the most common properties) from
colModel
items in thecmTemplate
. For example if you usewidth: 100
in all items ofcolModel
you should remove the property and add jqGrid optioncmTemplate: { width: 100 }
instead placing the propertywidth
with the same value inside of every item ofcolModel
. - I recommend you examine the value from Default column in the table with the properties of
colModel
in the documentation. You will find that placing ofalign: 'left'
,editable: false
,sortable: true
,stype: "text"
and some other properties are unneeded. I recommend you remove the properties. - If you have some native unique id for the data which come from the backend I would recommend yot to use it as the rowid. There are two option: 1) you need to display the column to the user. In the case you need just add
key: true
property incolModel
2) you don't need to display the id to the user. In the case you don't need create any hidden column with the data. Instead of that you can just addlocalReader: { id: "TransactionId" }
option to inform jqGrid where to get the rowids. The usage of native rowids will be especially practical for editing. Theid
parameter with rowid will be send by jqGrid to the server during editing. I recommend you to useprmNames: { id: "TransactionId" }
additionally. In the case jqGrid with name the property with rowid as"TransactionId"
instead of default name"id"
during editing. - You fill
colNames
with the values ofname
property ofcolModel
. You don't need do this. I recommend you don't specifycolNames
option at all in the case. In the case jqGrid will fillcolNames
internally with the values oflabel
property ofcolModel
or the value ofname
property iflabel
not exist. - I recommend you to hide columns which empty (
null
,""
," "
etc) values in all items of data. It makes the user easier to read the grid and improves the performance of the grid. Displaying of many columns is much more expensive for the web browser as displaying of many rows. So hiding unneeded columns can improve performance of the grid. - One more important important problem which I not yet fix in the demo is the following. You use wrong values of
name
property. Your current code contains columns havingname: "Employee Name"
orname: "Avg.Num Of Steps Occur"
. It's important to understand thatname
property will be used to buildid
attributes of some internal jqGrid elements and will be used in selectors. jQuery selectors should don't contains any meta-charackters (!"#$%&'()*+,./:;<=>?@[\]^``{|}~
). Additionallyid
of HTML 4 for example can't contains spaces. See here. I strictly recommend you to use only letters ([A-Za-z]), digits ([0-9]), hyphens ("-") or underscores ("_") in thename
. The first symbol should be a letter. If you don't follow the rule you can have many problems (problems in sorting, searching etc.). Probably you should setlabel: this.Name
property and used some rules to build correctname
value based onthis.Name
. You should include the property with originalthis.Name
property during editing, so that the result of editing will be sent the same as before fixing ofname
property.
结果,我将您的代码修改为以下内容: http://jsfiddle.net/z1ujyh02/6 /.我在下面包含的代码中最重要的部分:
As the result I modified your code to the following: http://jsfiddle.net/z1ujyh02/6/. The most important part of the code I included below:
var columnsData = "...", gridData = "...";
var mydata = $.parseJSON(gridData).BuildTransactionsDataTable, existingProperties = {},
numberTemplate = {formatter: 'number', sorttype: 'int'},
dateTemplate = {
editable: true,
searchoptions: {
dataInit: function (el) {
var self = this;
$(el).datepicker({
dateFormat: 'm/d/yy', maxDate: 0, changeMonth: true, changeYear: true,
onSelect: function (dateText, inst) {
setTimeout(function () {
self.triggerToolbar();
}, 50);
}
});
}
},
editoptions: {
dataInit: function (el) {
$(el).datepicker({
dateFormat: 'm/d/yy', maxDate: 0, changeMonth: true, changeYear: true
});
},
readonly: 'readonly'
}
}
dropdownTemplate = {
edittype: "select",
editable: true,
stype: "select"
};
$.each(mydata, function () {
var p;
for (p in this) {
if (this.hasOwnProperty(p) && this[p] !== null && (typeof this[p] === "string" && $.trim(this[p]) !== "")) {
existingProperties[p] = true;
}
}
});
var colname = [{ name: "TransactionId", sorttype: "int", key: true }];
//Loop into the column values collection and push into the array.
$.each($.parseJSON(columnsData).Table1, function () {
//Check the datatype of the column.
var cm = {
name: this.Name,
hidden: JSON.parse(this.IsHidden) || !existingProperties.hasOwnProperty(this.Name),
editoptions: this.DefaultValue != null && this.DefaultValue != "" ? { defaultValue: this.DefaultValue } : {},
editrules: { required: JSON.parse(this.IsRequired) }
};
switch (this.Datatype) {
case 'number':
$.extend(true, cm, { template: numberTemplate });
lastFieldName = cm.name; //Store the fieldName.
break;
case 'DateTime':
$.extend(true, cm, { template: dateTemplate });
lastFieldName = cm.name;
break;
case 'dropdown':
var values = this.ValueList.slice(0, -1);
$.extend(true, cm, {
template: dropdownTemplate,
editoptions: { value: ":Select;" + values, defaultValue: this.DefaultValue },
searchoptions: { value: ":All;" + values }
},
this.ValueType == "F" ? { label: this.ValueId } : {} );
break;
default:
break;
}
if (cm)
colname.push(cm);
});
//Binding grid Starts.
$("#TransactionsGrid").jqGrid({
//data: mydata,
datatype: "local",
hoverrows: false,
colModel: colname,
rowNum: 10,
rownumbers: true,
pager: "#TransactionsPager",
localReader: { id: "TransactionId" },
prmNames: { id: "TransactionId" },
viewrecords: true,
caption: "Transaction Details",
height: "auto",
gridview: true,
autoencode: true,
ignoreCase: true,
cmTemplate: { width: 100 },
onInitGrid: function () {
// get reference to parameters
var p = $(this).jqGrid("getGridParam");
// set data parameter
p.data = mydata;
}
});
这篇关于在jqgrid中优化动态创建的colmodel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!