是什么导致 jqgrid 事件多次触发?

What causes jqgrid events to fire multiple times?

我们的 jqgrid 在 initgrid 函数中配置,该函数被调用为就绪处理程序的最后一条语句。出于某种原因,gridcomplete 函数被多次调用。使用下面的代码,它被调用了两次,但它已经被调用了 3 次。两次就够糟了。多次单步执行后,我看不出是什么触发了 gridComplete 函数的第二次执行。

当我在 gridComplete 开始时点击调试器时,每次调用堆栈实际上都是相同的,唯一的区别是在 jqgrid 中调用了 'L':

有人知道为什么会这样吗?我们在 ASP.net MVC 应用程序中使用免费版本 4.13。

$(function(){
    ....
    initGrid();
}

function initGrid(){
$gridEl.jqGrid({
        xhrFields: {
            cors: false
        },
        url: "/IAConsult/GetWorkFlowIARequests",
        postData: {
            showAll: showAllVal,
            role: role,
            IsIAArchitect: userIsIA
        },
        datatype: "json",
        crossDomain: true,
        loadonce: true,
        mtype: 'GET',
        sortable: true,
        viewrecords: true,
        pager: '#workFlowIAGridPager',
        multiselect: true,
        rowNum: 50,
        autowidth: true,
        colModel: [...],
        beforeSelectRow: function (rowid, e) {
            var $myGrid = $(this),
                i = $.jgrid.getCellIndex($(e.target).closest('td')[0]),
                cm = $myGrid.jqGrid('getGridParam', 'colModel');
            return (cm[i].name === 'cb');
        },
        jsonReader: {
            repeatitems: true,
            root: "IAConsultWorkflowRequestsList"
        },
        beforeSubmitCell: function (rowid, name, value, iRow, iCol) {
            return {
                gridData: gridData
            };
        },
        serializeCellData: function (postdata) {
            return JSON.stringify(postdata);
        },
        gridComplete: function () {
            console.log('grid complete');
            let rowIDs = $gridEl.getDataIDs();
            let inCompleteFlag = false;
            let dataToFilter = $gridEl.jqGrid('getGridParam', 'lastSelectedData').length == 0
                ? $gridEl.jqGrid("getGridParam", "data")
                : $gridEl.jqGrid('getGridParam', 'lastSelectedData');
            let $grid = $gridEl, postfilt = "";
            let localFilter = $gridEl.jqGrid('getGridParam', 'postData').filters;
            let columnNames = columns.split(',');

            $('.moreItems').on('click', function () {
                $.modalAlert({
                    body: $(this).data('allitems'),
                    buttons: {
                        dismiss: {
                            caption: 'Close'
                        }
                    },
                    title: 'Design Participants'
                });
            });

            rowCount = $gridEl.getGridParam('records');
            gridViewRowCount = rowCount;

            let getUniqueNames = function (columnName) {
                ...             };

            let buildSearchSelect = function (uniqueNames) {
                var values = {};
                values[''] = 'All';
                $.each(uniqueNames,
                    function () {
                        values[this] = this;
                    });
                return values;
            };

            let setSearchSelect = function (columnName) {
                ...

            };

            function getSortOptionsByColName(colName) {
                ...
            }



            $grid.jqGrid("filterToolbar",
                { stringResult: true, searchOnEnter: true });


            if (localFilter !== "" && localFilter != undefined) {
                globalFilter = localFilter;
            }

            let grid = $gridEl.jqGrid("setGridParam",
                {
                    postData: {
                        "filters": globalFilter,
                        showAll: showAllVal,
                        role: role,
                        IsIAArchitect: userIsIA
                    },
                    search: true,
                    forceClientSorting: true
                });

            //grid.trigger("reloadGrid");
            //Ending Filter code


            for (i = 0; i < columnNames.length; i++) {

                var htmlForSelect = '<option value="">All</option>';
                var un = getUniqueNames(columnNames[i]);
                var $select = $("select[id='gs_workFlowIAGrid_" + columnNames[i] + "']");
                for (j = 0; j < un.length; j++) {
                    val = un[j];

                    htmlForSelect += '<option value="' + val + '">' + val + '</option>';
                }
                $select.find('option').remove().end().append(htmlForSelect);
            }
            debugger;
        },

        // all grid parameters and additionally the following
        loadComplete: function () {
            $gridEl.jqGrid('setGridWidth', $(window).width(), true);
            $gridEl.setGridWidth(window.innerWidth - 20);
        },

        height: '100%'
    });

我个人几乎从不使用 gridComplete 回调。它存在于免费的 jqGrid 中,主要是为了向后兼容。我建议您阅读 the old answer,其中描述了 gridCompleteloadComplete 之间的差异。

一些额外的建议:在回调中注册事件是危险的(参见 $('.moreItems').on('click', ...)。如果您需要在网格内部单击时执行一些操作,那么我建议您使用 beforeSelectRow。许多事件,包括 click 事件支持事件冒泡,网格内未处理的点击将被冒泡到父 <table> 元素。您已经使用了 beforeSelectRow 回调并且 e.target 为您提供了有关点击元素的完整信息。

我建议您另外不要使用 setGridParam 方法,这会降低性能。 setGridParam 方法默认深度复制 所有 内部参数,包括像 data 这样的数组,它可以很大。顺便说一句,改变 setGridParam 的一个小参数可能会很昂贵。如果您需要修改 jqGrid 的参数,那么您可以使用 getGridParam 而无需 额外参数来获取 reference 到内部对象,其中包含所有 jqGrid 参数。之后,您可以使用参数对象访问读取或修改 jqGrid 的参数。有关小代码示例,请参见

同时添加 属性 加载一次:真 可能有帮助。