我正在尝试使用dgrid和Request dstore的派生来定期显示和刷新一些服务器数据。数据是分页的,需要定期更新。作为第一个天真的方法,我试图用setInterval调用Dgrid.refresh()。但是,这会导致网格行的完全重建,从而在视觉上产生闪烁效果。使用Trackable到商店没有帮助。任何人都可以建议我如何刷新dgrid中只会更新已更改行的行?
以下是我的代码重现问题:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>DGrid flickering on slow updates</title>
<style>
@import "./dojo-release-1.11.1/dojo/resources/dojo.css";
@import "./dojo-release-1.11.1/dijit/themes/claro/claro.css";
@import "./META-INF/resources/webjars/dgrid/1.0.0/css/dgrid.css";
@import "./META-INF/resources/webjars/dgrid/1.0.0/css/skins/claro.css";
html, body {
padding: 10px;
width: 100%;
height: 100%;
}
</style>
<script>
var dojoConfig = {
async:true,
baseUrl: "./",
packages:[
{ name:"dojo", location:"dojo-release-1.11.1/dojo" },
{ name:"dijit", location:"dojo-release-1.11.1/dijit" },
{ name:"dgrid", location:"META-INF/resources/webjars/dgrid/1.0.0" },
{ name:"dstore", location:"META-INF/resources/webjars/dstore/1.1.1" }
]
};
</script>
<script src="dojo-release-1.11.1/dojo/dojo.js"></script>
<script>
require(["dojo/parser",
"dojo/dom",
"dojo/_base/declare",
"dstore/Store",
"dstore/Trackable",
"dstore/Cache",
"dstore/Memory",
"dstore/QueryResults",
"dojo/Deferred",
"dgrid/Grid",
"dgrid/Keyboard",
"dgrid/Selection",
"dgrid/extensions/Pagination",
"dojo/domReady!"],
function(parser, dom, declare, Store, Trackable, Cache, Memory, QueryResults, Deferred, Grid, Keyboard, Selection, Pagination)
{
parser.parse();
console.log("Parsed");
var makeSlowRequest =
function(kwArgs)
{
var responseDeferred = new Deferred();
var responsePromise = responseDeferred.promise;
// resolve promise in 2 seconds to simulate slow network connection
setTimeout(function ()
{
console.log("Generating response");
var data = {items: [], total: 100};
kwArgs = kwArgs || {start:0, end:100};
for(var i = kwArgs.start; i < kwArgs.end; i++)
{
data.items.push({id: "id-" + i,
name: "test-" + i,
value: Math.floor((Math.random() * 10) + kwArgs.start)
});
}
responseDeferred.resolve(data);
}, 2000);
return new QueryResults(responsePromise.then(function (data) { return data.items; }),
{ totalLength: responsePromise.then(function (data) { return data.total;}) });
};
var SlowStore = declare("SlowStore",
[Store, Trackable],
{ fetch: function (kwArgs) { return makeSlowRequest(kwArgs); },
fetchRange: function (kwArgs) { return makeSlowRequest(kwArgs); }
});
var store = new SlowStore();
var TestGrid = declare([Grid, Keyboard, Selection, Pagination]);
var grid = new TestGrid({
collection: store,
columns: {name: "Name", value: "Value"},
rowsPerPage: 10,
selectionMode: 'single',
cellNavigation: false,
className: 'dgrid-autoheight',
pageSizeOptions: [10, 20],
adjustLastColumn: true
}, dom.byId("grid"));
grid.startup();
// update grid every 5 seconds
var timer = setInterval(function(){console.log("Refreshing grid"); grid.refresh();}, 5000);
});
</script>
</head>
<body class="claro">
<div id="grid"></div>
</body>
</html>
我猜测而不是调用refresh我需要从dgrid获取请求范围(可能使用gotoPage上的方面)并调用store.fetchRange(),迭代结果,将每个项目与之前的结果进行比较并调用store。更新或store.add或store.delete。我想这会给我我想要的东西,但在采用这种方法之前,我想知道是否有更简单的方法来刷新dgrid与更新的数据。使用缓存存储不起作用,因为它希望从服务器获取所有数据:
var store = Cache.create(new SlowStore(), {
cachingStore: new (Memory.createSubclass(Trackable))()
});