Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 自动取消jqGrid请求_Javascript_Ajax_Jqgrid_Xmlhttprequest - Fatal编程技术网

Javascript 自动取消jqGrid请求

Javascript 自动取消jqGrid请求,javascript,ajax,jqgrid,xmlhttprequest,Javascript,Ajax,Jqgrid,Xmlhttprequest,我想这个用户问的问题和我问的相同,但提出他的问题的原因不同,所以他接受了不同的解决方案。我需要做他最初要求的事情: 我的jqGrid有一个搜索工具栏(显示在列标题下方但在数据上方的输入字段)。大多数列都有下拉列表(stype=select),其中列出了该列的可用筛选选项,顶部有一个“All”选项。使用填充jqGrid的JSON数据进行响应的服务器端代码非常复杂,因此有点慢,尤其是在没有太多过滤条件的情况下。这意味着,如果用户选择“全部”,可能需要几秒钟才能显示任何结果。这本身没有问题,但如果用

我想这个用户问的问题和我问的相同,但提出他的问题的原因不同,所以他接受了不同的解决方案。我需要做他最初要求的事情:

我的jqGrid有一个搜索工具栏(显示在列标题下方但在数据上方的输入字段)。大多数列都有下拉列表(stype=select),其中列出了该列的可用筛选选项,顶部有一个“All”选项。使用填充jqGrid的JSON数据进行响应的服务器端代码非常复杂,因此有点慢,尤其是在没有太多过滤条件的情况下。这意味着,如果用户选择“全部”,可能需要几秒钟才能显示任何结果。这本身没有问题,但如果用户在响应返回之前选择了另一个过滤器,网格不会取消现有请求,也不会提交新请求,因此在用户进行第二次选择后的某个时间点,网格会更新以显示第一次选择的响应。此外,当您更改过滤器选择时,网格会自动更新,因此为了让它显示您想要的数据,您必须将您的选择更改为其他内容,等待加载,然后再将其更改回来

以下是我迄今为止所尝试的:

$(document).ready(setupGrid);

var currentGridRequest;

function setupGrid() {
    var grid = $("#grid").jqGrid({
        ...
        loadError: function(xhr, status, error) {
            currentGridRequest = undefined;
        },
        loadComplete: function(data) {
            currentGridRequest = undefined;
        },
        loadBeforeSend: function(xhr, settings) {
            if (currentGridRequest !== undefined) {
                currentGridRequest.abort();
            }
            currentGridRequest = xhr;
        }
    });
}
我遇到的问题是,如果飞行中已有请求,loadBeforeSend事件实际上不会触发。我尝试了事件文档页面()中的其他事件:beforeRequest和jqGridToolbarBeforeSearch都表现出相同的行为

如何中止飞行中的请求并根据用户最近的选择继续搜索?这是jqGrid中的一个bug吗?我最初在版本4.2中遇到这个问题;我刚刚升级到4.4.4,但此行为没有改变

看看jqGrid代码,如果不改变jqGrid代码本身,我看到的行为似乎是不可避免的。jqGrid在每个请求开始时设置一个标志(ts.grid.hDiv.loading),并在结束时清除它;设置此标志时,不会提交新的筛选条件,也不会触发任何事件


我还考虑修改JSON响应,使其包含请求条件,然后编写一些JS代码将响应与当前选择的条件进行比较。如果它们不匹配,我将忽略响应,不将其渲染到网格。因为jqGrid甚至没有提交第二组标准,所以这个选项已经不存在了(即使我可以解决这个问题,我目前的方法似乎更可取)。

我找到了一种方法来做我想做的事情。我在多个地方使用jqGrid(在少数情况下包括同一页面上的多个网格),因此我将其分解成一个可以从任何地方调用的函数,该函数包含自己的范围,用于管理是否存在当前请求;只需向它传递一个网格,它就会附加所有必要的事件处理程序。请注意,这将覆盖您为相关事件定义的任何现有处理程序

function applyJqgridHandlers(grid) {
    (function(self, undefined) {
        var currentRequest;
        function abortCurrentRequestIfAny() {
            if (currentRequest !== undefined) {
                currentRequest.abort();
            }
        }
        self.clearCurrentRequest = function() {
            abortCurrentRequestIfAny();
            currentRequest = undefined;
        };
        self.setCurrentRequest = function(xhr) {
            abortCurrentRequestIfAny();
            currentRequest = xhr;
        };
    })(grid.currentRequestHolder = {});

    grid.currentRequestHolder.clearCurrentRequest();
    grid.jqGrid('setGridParam', {
        loadError: function(xhr, status, error) {
            grid.currentRequestHolder.clearCurrentRequest();
        },
        loadBeforeSend: function(xhr, settings) {
            grid.currentRequestHolder.setCurrentRequest(xhr);
        },
        loadComplete: function(data) {
            grid.currentRequestHolder.clearCurrentRequest();
        }
    });
    grid.bind('jqGridToolbarBeforeSearch', function() {
        grid.currentRequestHolder.clearCurrentRequest();
        this.grid.hDiv.loading = false;
    });
};
然后,我只需在setupGrid()的末尾添加对该函数的调用


<>这个代码明确地清除了TS.GID.HDIV.Load标志,这不是发布的JQGrand API的一部分,所以我认为这个解决方案相当脆弱;不能保证它在jqGrid的未来版本中会继续工作。如果有人对解决这个问题的更好(不那么脆弱)方法有任何建议,我洗耳恭听。:)

@JakeRobb谢谢你的主意!我已经自由地创建了一个可以普遍使用的函数,而无需禁用原始jqGrid的任何功能

在jqGrid版本5.2.1上测试

jqGrid快速搜索 a、 k.a.如果用户应用了新筛选器,则自动取消旧请求

/**
*添加使用jqGrid工具栏快速搜索的功能
*
*@param jqGridInstance字符串|对象
*
*@作者基里尔·雷兹尼克
*/
var jqGridRapidSearch=函数(jqGridInstance){
var currentRequest=null,
abortRequest=函数(){
如果(currentRequest!==null){
currentRequest.abort();
}
},
setRequest=函数(xhr){
中止任务();
currentRequest=xhr;
},
clearRequest=函数(){
中止任务();
currentRequest=null;
},
$jqGrid=null;
if($.type(jqGridInstance)=='string'){
$jqGrid=$(jqGridInstance);
}else if($.type(jqGridInstance)=='object'&&&$.type(jqGridInstance.jquery)=='string'){
$jqGrid=jqGridInstance;
}否则{
抛出“jqGridRapidSearch需要有效的jqGrid实例参数:网格ID字符串或jQuery对象”;
}
$jqGrid.on('jqGridLoadBeforeSend',函数(e、xhr、设置){
设置请求(xhr);
});
$jqGrid.on('jqGridLoadComplete',函数(e,数据){
clearRequest();
});
$jqGrid.on('jqGridLoadError',函数(e、xhr、状态、错误){
clearRequest();
});
$jqGrid.on('jqGridToolbarBeforeSearch',函数(e){
clearRequest();
});

};
Hi@Aternus,我正在使用jqgrid 4.3.1版本,我检查了4.3.1 jqgrid不支持事件触发器处理程序,我们可以使用其他选项吗