【问题标题】:Duplicated rows when sorting dgrid 0.3.6对 dgrid 0.3.6 进行排序时出现重复的行
【发布时间】:2013-06-12 18:45:22
【问题描述】:

我一直在使用 dgrid 0.3.2 和 JsonRest 来显示数据表。最近,我一直在考虑升级到 dgrid 0.3.6 或 0.3.7。事情的工作原理大致相同,但似乎在较新版本的 dgrid 中,如果用户单击列标题以足够快地排序,网格将开始显示重复的行。我已经验证响应 JSON 和范围是正确的,当我们使用 dgrid 0.3.2 时似乎没有发生这种情况。

这是一个简单的测试用例,它重现了问题,并模仿了我们设置网格和存储的方式。难道我做错了什么?如果我不将 JsonRest 包装在缓存中,我不会遇到此问题,因此我确定问题存在,但我不确定不缓存 JSON 响应的性能后果。

<!doctype html>
<html>

<head>
<%
    String dgridVer = request.getParameter("dgridVer");
    if (dgridVer==null) { dgridVer = "0.3.6"; }
%>
<script type="text/javascript">
    var dojoConfig = {
        isDebug: true,
        baseUrl: 'dojo',
        packages: [
            { name: 'dojo',      location: 'dojo' },
            { name: 'dijit',     location: 'dijit' },
            { name: 'dojox',     location: 'dojox' },
            { name: 'dgrid',     location: 'dgrid-<%=dgridVer%>' },
            { name: 'put-selector',     location: 'put-selector' },
            { name: 'xstyle',    location: 'xstyle' },
            { name: 'datagrid', location: '../datagrid' }
        ]
    };
</script>
<script src="dojo/dojo/dojo.js"></script>
</head>

<body>
Try sorting a column as fast as you can.  Look for duplicated rows.<br>
Using dgrid version: <%=dgridVer %><p>

<div id='gridDiv'></div>

<script>
require(['dgrid/Grid', 'dgrid/extensions/Pagination', 'dojo/store/JsonRest',
            'dojo/store/Cache', 'dojo/store/Memory', 'dojo/_base/declare', 'dojo/domReady!'], 
    function(Grid, Pagination, JsonRest,
                Cache, Memory, declare) {

    var columns = [
        { field: "first", label: "First Name" },
        { field: "last",  label: "Last Name" },
        { field: "age",    label: "Age" }
    ];

    var store = new JsonRest({
        target: 'testData.jsp',
        sortParam: "sortBy"
    });
    store = Cache(store, Memory());

    var grid = new (declare([Grid, Pagination]))({
        columns: columns,
        store: store,
        loadingMessage: 'Loading...',
        rowsPerPage: 4,
        firstLastArrows: true
    }, 'gridDiv');

});
</script>

</body>

</html>

【问题讨论】:

    标签: javascript dojo dgrid


    【解决方案1】:

    检查Cache.js 的默认实现,尤其是queryqueryEngine 函数。默认情况下,它们总是首先到达主存储,在您的情况下是 JsonRest 存储。只有在加载数据后,缓存存储才会更新(在您的情况下为 Memory 存储)。

    现在,如果您检查 DGrid List.js 文件中的函数 _setSort 和 DGrid OnDemandList.js 中的函数 refresh,您将看到默认情况下 DGrid 调用当前 storequery 方法获取以不同方式排序的项目的新列表。在您的情况下,该商店是dojo/store/Cache

    所以,总而言之,当用户单击要排序的列时,DGrid 会查询Cache,后者又会查询JsonRest,后者又会查询服务器,然后服务器返回新数据,然后@987654336 @ 商店在Memory 商店。

    您实际上可以使用 Firebug(Firefox 扩展)来确认这一点。就我而言,每当我尝试排序时,Firebug 都会向服务器显示一个新请求以获取新数据。

    当有很多行时这很有意义,因为 DGrid 旨在仅加载第一批行,然后在用户向下滚动时更新网格。当排序发生变化时,第一批可见的行可能不同并且可能尚未加载,因此 DGrid 必须先加载它们。

    但在我的情况下,Json 请求在单个请求期间返回所有数据。我不喜欢默认实现并实现了我自己的缓存存储,它在更改排序时不需要访问服务器。我现在无法分享实现,但当我有时间整理代码时会尝试做。

    就目前而言,如果您仅切换到 JsonRest 存储,您应该不会注意到任何性能问题(考虑到在更改排序时无论如何都会访问服务器)。

    我不确定是什么导致了重复行的具体问题,但我记得当我的缓存存储没有正确实现时也看到了它(如果我没记错的话,它与加载数据时的延迟请求有关)。您可以尝试通过在Cache 存储的getquery 函数中添加(再次使用Firebug)断点来调试它。我敢打赌,DGrid 尝试使用 get 方法(命中缓存)加载特定行,而在用户更改排序后,query 请求仍在从服务器加载数据。但我可能是错的,所以如果可以的话,请先尝试确认。

    【讨论】:

    • 抱歉这么久才回复。谢谢你的回复,你在想我在想什么。我无法弄清楚 dgrid 代码中发生了什么变化,但是当这种行为发生变化时,确实将其隔离到 0.3.5。我创建了 issue 635 并提到了我想出的解决方法 - 只需在当前运行排序时禁用列排序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2013-12-23
    • 2011-08-22
    • 1970-01-01
    • 2015-10-05
    • 2013-01-07
    相关资源
    最近更新 更多