什么是在网格中显示实时数据(证券交易所,天气......)的更好方法? 我用这个方法:
setInterval(function(){
jQuery("#list1").trigger('reloadGrid');
}, 5000);
答案 0 :(得分:16)
我觉得你的问题非常有趣。我认为这个问题对许多其他用户来说可能很有意思。所以来自我的+1。
setInterval
的用法在常见的浏览器独立案例中以最佳方式联系我。我应该将setInterval
的结果保存在变量中,以便能够使用clearInterval
来阻止它。
[{current:true}]
的另一个小改进是使用trigger
(有关详细信息,请参阅the answer)作为var $grid = jQuery("#list1"), timer;
timer = setInterval(function () {
$grid.trigger('reloadGrid', [{current: true}]);
}, 5000);
的第二个参数:
beforeProcessing
它将在重新加载网格时保存选择。
现在许多新的网络浏览器都支持WebSocket。因此,如果Web浏览器支持它,最好使用这种方式。如果数据没有在服务器上更改并且阻止服务器永久池化,那么可以跳过不需要的网格重新加载。
在我看来,一种更常见的方式也非常有趣。如果可以使用网格数据的最后更改的某种时间戳,则可以验证数据是否被更改。可以在服务器上使用ETag或一些通用的附加方法。
填充jqGrid的success的当前jQuery.ajax回调允许您使用jqXHR.satus
回调修改服务器响应,但它是不允许您根据xhr.status
值停止jqGrid刷新(在当前的jqGrid代码中它将是textStatus
)。对jqGrid代码the line的小修改将允许您在服务器上未更改数据的情况下停止jqGrid刷新。可以为st
测试"notmodified"
(jqGrid的当前代码中的jqXHR.satus
)或xhr.status
(当前jqGrid代码中的prmNames: { nd:null }
){{{ 3}}。使用该方案非常重要,您应使用ETag
选项并设置Cache-Control: private, max-age=0
和success
(请参阅304,here和{{3其他信息)。
更新:我尝试根据我的上一个建议创建演示项目,发现它并不像我上面描述的那么容易。不过我做到了。困难在于因为人们无法从jQuery.ajax中的服务器响应中看到304代码。原因是here
中的以下位置对于由用户代理导致的 304 Not Modified 响应 生成的条件请求用户代理必须像服务器一样 使用适当的内容给出了 200 OK 响应。用户代理 必须允许作者请求标头覆盖自动缓存 验证(例如 If-None-Match 或 If-Modified-Since ),在这种情况下 304 Not Modified 响应必须通过。
因此,您可以在服务器响应的$.ajax
XMLHttpRequest
处理程序中找到 200 OK 状态,而不是 304 Not Modified 。似乎ETag
从缓存中获得完整响应,包括所有HTTP头。因此,我决定更改缓存数据的分析,只是将ETag
从上一个HTTP响应保存为新的jqGrid参数,并使用保存的数据测试新响应的beforeProcessing
。
我看到你使用PHP(我不会使用:-()。但是我可以阅读和理解PHP代码。我希望你能以同样的方式阅读C#代码并理解主要思想。所以你将能够在PHP中实现相同的功能。
现在我描述一下我的所作所为。首先,我修改了使用if ($.isFunction(ts.p.beforeProcessing)) {
ts.p.beforeProcessing.call(ts, data, st, xhr);
}
回调的jqGrid源代码的here
if ($.isFunction(ts.p.beforeProcessing)) {
if (ts.p.beforeProcessing.call(ts, data, st, xhr) === false) {
endReq();
return;
}
}
到
beforeProcessing
它允许从beforeProcessing
返回false以跳过数据刷新 - 跳过数据处理。我在演示中使用的ETag
的实现基于用法beforeProcessing: function (data, status, jqXHR) {
var currentETag = jqXHR.getResponseHeader("ETag"), $this = $(this),
eTagOfGridData = $this.jqGrid('getGridParam', "eTagOfGridData");
if (currentETag === eTagOfGridData) {
$("#isProcessed").text("Processing skipped!!!");
return false;
}
$this.jqGrid('setGridParam', { eTagOfGridData: currentETag });
$("#isProcessed").text("Processed");
}
:
$("#isProcessed").text("Processed");
行$("#isProcessed").text("Processing skipped!!!");
或行"Processed"
在div中设置"Processing skipped!!!"
或GET http://localhost:34336/Home/DynamicGridData?search=false&rows=10&page=1&sidx=Id&sord=desc&filters= HTTP/1.1
X-Requested-With: XMLHttpRequest
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://localhost:34336/
Accept-Language: de-DE
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; LEN2)
Host: localhost:34336
If-None-Match: D5k+rkf3T7SDQl8b4/Y1aQ==
Connection: Keep-Alive
文本,我用它直观地指示来自服务器的数据用于填充网格。
在演示中,我显示两个具有相同数据的网格。我用的第一个网格用于编辑数据。第二个网格每秒从服务器提取数据。如果服务器上的数据未更改,则HTTP流量将如下所示
HTTP请求:
HTTP/1.1 304 Not Modified
Server: ASP.NET Development Server/10.0.0.0
Date: Sun, 06 May 2012 19:44:36 GMT
X-AspNet-Version: 4.0.30319
X-AspNetMvc-Version: 2.0
Cache-Control: private, max-age=0
ETag: D5k+rkf3T7SDQl8b4/Y1aQ==
Connection: Close
HTTP响应:
HTTP/1.1 200 OK
所以如果数据未更改,则不会从服务器传输数据。如果数据发生更改,HTTP标头将以ETag
启动,并包含$grid1.trigger('reloadGrid', [{ current: true}]);
个新修改数据以及数据页本身。
可以使用"刷新"手动刷新网格数据。导航器的按钮或使用"启动自动刷新"按钮,每秒执行loadui: "disable"
。该页面看起来像
我用颜色框标记了页面底部最重要的部分。如果有一个"Processed"
选项,则在拉动服务器期间根本看不到网格上的任何更改。如果有人评论了一个人会看到的选项"正在加载......" div很短的时间,但没有网格会闪烁。
开始"自动清新"一个人会看到如下图片
如果要更改第一个网格中的某一行,则第二个网格将在一秒钟内更改,其中一个将显示"Processing skipped!!!"
文本,该文本将在一秒内更改为public JsonResult DynamicGridData(string sidx, string sord, int page, int rows,
bool search, string filters)
{
Response.Cache.SetCacheability (HttpCacheability.ServerAndPrivate);
Response.Cache.SetMaxAge (new TimeSpan (0));
var serializer = new JavaScriptSerializer();
... - do all the work and fill object var result with the data
// calculate MD5 from the returned data and use it as ETag
var str = serializer.Serialize (result);
byte[] inputBytes = Encoding.ASCII.GetBytes(str);
byte[] hash = MD5.Create().ComputeHash(inputBytes);
string newETag = Convert.ToBase64String (hash);
Response.Cache.SetETag (newETag);
// compare ETag of the data which already has the client with ETag of response
string incomingEtag = Request.Headers["If-None-Match"];
if (String.Compare (incomingEtag, newETag, StringComparison.Ordinal) == 0) {
// we don't need return the data which the client already have
Response.SuppressContent = true;
Response.StatusCode = (int)HttpStatusCode.NotModified;
return null;
}
return Json (result, JsonRequestBehavior.AllowGet);
}
文本。< / p>
服务器端的相应代码(我使用ASP.NET MVC)主要是以下
beforeProcessing
我希望代码的主要思想也适用于那些不仅使用ASP.NET MVC的人。
您可以下载项目XMLHttpRequest specification。
更新:我发布了the lines以允许false
通过返回{{1}}值来中断服务器响应的处理。主要的jqGrid代码中已包含相应的更改(请参阅here)。所以jqGrid的下一个版本将包含它。