是什么导致 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,其中描述了 gridComplete
和 loadComplete
之间的差异。
一些额外的建议:在回调中注册事件是危险的(参见 $('.moreItems').on('click', ...
)。如果您需要在网格内部单击时执行一些操作,那么我建议您使用 beforeSelectRow
。许多事件,包括 click
事件支持事件冒泡,网格内未处理的点击将被冒泡到父 <table>
元素。您已经使用了 beforeSelectRow
回调并且 e.target
为您提供了有关点击元素的完整信息。
我建议您另外不要使用 setGridParam
方法,这会降低性能。 setGridParam
方法默认深度复制 所有 内部参数,包括像 data
这样的数组,它可以很大。顺便说一句,改变 setGridParam
的一个小参数可能会很昂贵。如果您需要修改 jqGrid 的参数,那么您可以使用 getGridParam
而无需 额外参数来获取 reference 到内部对象,其中包含所有 jqGrid 参数。之后,您可以使用参数对象访问读取或修改 jqGrid 的参数。有关小代码示例,请参见 。
同时添加 属性
加载一次:真
可能有帮助。
我们的 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,其中描述了 gridComplete
和 loadComplete
之间的差异。
一些额外的建议:在回调中注册事件是危险的(参见 $('.moreItems').on('click', ...
)。如果您需要在网格内部单击时执行一些操作,那么我建议您使用 beforeSelectRow
。许多事件,包括 click
事件支持事件冒泡,网格内未处理的点击将被冒泡到父 <table>
元素。您已经使用了 beforeSelectRow
回调并且 e.target
为您提供了有关点击元素的完整信息。
我建议您另外不要使用 setGridParam
方法,这会降低性能。 setGridParam
方法默认深度复制 所有 内部参数,包括像 data
这样的数组,它可以很大。顺便说一句,改变 setGridParam
的一个小参数可能会很昂贵。如果您需要修改 jqGrid 的参数,那么您可以使用 getGridParam
而无需 额外参数来获取 reference 到内部对象,其中包含所有 jqGrid 参数。之后,您可以使用参数对象访问读取或修改 jqGrid 的参数。有关小代码示例,请参见
同时添加 属性 加载一次:真 可能有帮助。