javascript - 自动取消jqGrid请求

标签 javascript ajax jqgrid xmlhttprequest

我认为该用户提出的问题与我提出的问题相同,但他提出问题的原因不同,因此他接受了不同的解决方案。我需要做他最初要求的事情:

Automatically cancelling jqgrid request

我的 jqGrid 有一个搜索工具栏(显示在列标题下方但数据上方的输入字段)。大多数列都有下拉列表 (stype=select),其中列出了该列的可用过滤器选项,顶部有一个“全部”选项。使用填充我的 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 事件实际上不会触发。我尝试了事件文档页面 ( http://www.trirand.com/jqgridwiki/doku.php?id=wiki:events ) 中的其他事件:beforeRequest 和 jqGridToolbarBeforeSearch 都表现出相同的行为。

我该怎么做才能中止进行中的请求并继续根据用户最近的选择进行搜索?这是 jqGrid 中的错误吗?我最初是在 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.grid.hDiv.loading 标志,它不是已发布的 jqGrid API 的一部分,因此我认为此解决方案相当脆弱;不能保证它会继续为 future 版本的 jqGrid 工作。如果有人对解决此问题的更好(不那么脆弱)的方法有任何建议,我会洗耳恭听。 :)

关于javascript - 自动取消jqGrid请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14881790/

相关文章:

php - 在动态创建的 div-tag php javascript 中回显

javascript - 使用 jQuery 获取 session 值

jquery - 带有 Twitter Bootstrap 的响应式/流畅的 jQGrid

Javascript - 数组的平均值不正确?

javascript - 语法错误: Unexpected token o in JSON at position 1 EXPRESS

javascript - 无法从我的 angular2 View 文件夹中渲染 index.html 文件

php - JavaScript 等价于 PHP 的 preg_replace

javascript - 使用 Ajax 编写服务器文本文件

jqGrid 在编辑单元格时只允许数字

jquery - JqG​​rid - 在 loadComplete 事件内触发重新加载