优化jqgrid中动态创建的colmodel [英] Optimize the dynamically created colmodel in jqgrid

查看:24
本文介绍了优化jqgrid中动态创建的colmodel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究动态绑定的 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

更新:

我必须在我的控制器中处理的情况以及在客户端(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 片段的数据,那么我建议您使用 autoencode: true jqGrid 的选项,
  • the value of parameter height can be wither a number like height: 250 or string "auto" or "100%". The value '250px' is incorrect. My favorit value for height is "auto".
  • you should remove unknown id option of jqGrid (see id: '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 use autoencode: 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:

  1. 删除网格的 sortnamesortorder 选项.大型数据集的排序可能需要时间.没有sortname(或sortname: "")意味着显示unsorted数据.它将提高数据初始加载的性能.
  2. 删除网格的 data 选项并将其设置在 onInitGrid 回调中:
  1. Remove sortname and sortorder options of the grid. Sorting of large dataset can take time. No sortname (or sortname: "") means displaying unsorted data. It will improve the performace of initial loading of data.
  2. Remove data option of the grid and set it inside of onInitGrid 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;
    }
});

演示来自 答案 加载 90000 行数据,加载大约需要 52-130 毫秒,具体取决于我使用的网络浏览器.在我看来,这是一个好时机.没有技巧(参见 demo)加载数据大约需要 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 放置在 colModel每个 项中.
  • 我建议您使用 文档.你会发现 align: 'left', editable: false, sortable: true, stype: "text" 和其他一些属性不需要.我建议您删除这些属性.
  • 如果您有来自后端的数据的本机唯一 ID,我建议您将其用作 rowid.有两个选项:1)您需要向用户显示该列.如果您只需要在 colModel 中添加 key: true 属性 2) 您不需要向用户显示 id.如果您不需要使用数据创建任何隐藏列.取而代之的是,您可以添加 localReader: { id: "TransactionId" } 选项来通知 jqGrid 从何处获取 rowid.原生 rowid 的使用对于编辑来说尤其实用.带有rowid 的id 参数将在编辑期间由jqGrid 发送到服务器.我建议您另外使用 prmNames: { id: "TransactionId" }.在 jqGrid 的情况下,名称为 rowid 的属性为 "TransactionId" 而不是默认名称 "id" 在编辑期间.
  • 您用 colModelname 属性的值填充 colNames.你不需要这样做.我建议您在这种情况下根本不要指定 colNames 选项.在这种情况下,jqGrid 将使用 colModellabel 属性的值或 name 属性的值在内部填充 colNames如果 label 不存在.
  • 我建议您在数据.它使用户更容易阅读网格并提高网格的性能.对于 Web 浏览器来说,显示多列的成本要比显示多行的成本高得多.因此隐藏不需要的列可以提高网格的性能.
  • 一个更重要的问题我还没有在演示中解决如下.您使用了错误的 name 属性值.您当前的代码包含具有 name: "Employee Name"name: "Avg.Num Of Steps Occur" 的列.重要的是要了解 name 属性将用于构建一些内部 jqGrid 元素的 id 属性,并将在选择器中使用.jQuery 选择器不应包含任何 元字符 (!"#$%&'()*+,./:;<=>?@[]^``{|}~). 另外 id of HTML 4 例如不能包含空格.请参阅这里.我强烈推荐您只能在 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 of name properties. If you remove index properties jqGrid internally will create correct index values. So I strictly recommend all don't specify index properties in colModel.
  • I recommend you to move all common properties (or the most common properties) from colModel items in the cmTemplate. For example if you use width: 100 in all items of colModel you should remove the property and add jqGrid option cmTemplate: { width: 100 } instead placing the property width with the same value inside of every item of colModel.
  • 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 of align: '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 in colModel 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 add localReader: { id: "TransactionId" } option to inform jqGrid where to get the rowids. The usage of native rowids will be especially practical for editing. The id parameter with rowid will be send by jqGrid to the server during editing. I recommend you to use prmNames: { 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 of name property of colModel. You don't need do this. I recommend you don't specify colNames option at all in the case. In the case jqGrid will fill colNames internally with the values of label property of colModel or the value of name property if label 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 having name: "Employee Name" or name: "Avg.Num Of Steps Occur". It's important to understand that name property will be used to build id attributes of some internal jqGrid elements and will be used in selectors. jQuery selectors should don't contains any meta-charackters (!"#$%&'()*+,./:;<=>?@[]^``{|}~). Additionally id 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 the name. 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 set label: this.Name property and used some rules to build correct name value based on this.Name. You should include the property with original this.Name property during editing, so that the result of editing will be sent the same as before fixing of name 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屋!

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