我创建了一个转发器,现在我想在每1分钟后刷新一次转发器。 打击是我的代码:
<asp:Repeater ID="gvd" runat="server">
<ItemTemplate>
<tr class="gradeA">
<td>
<asp:Label ID="lblcategory" runat="server" Text='<%#Eval("Firstname")%>'></asp:Label>
</td>
<td>
<asp:Label ID="lblcontent" runat="server" Text='<%#Eval("Lastname")%>'></asp:Label>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
它提供了完美的输出,但现在我想通过javascript刷新整个转发器,因为使用updatepanel它会增加服务器上的负载
那我怎么能通过javascript做到这一点?
答案 0 :(得分:5)
SignalR是为了解决您所描述的问题。
这是你的情况: 您想要一种方法来显示可能不断变化的信息。在任何时候,都应该显示最新的信息。
以Web窗体为中心的方法是使用UpdatePanel。但是我自己和some others并不喜欢那些。它们通常会在以后出现问题,因为它们不能很好地与其他技术配合使用。它们也“昂贵”,它们在客户端和服务器之间来回传输大量数据,耗费带宽和资源。
deostroll稍微触及的另一种方法是使用AJAX定期轮询服务器以获取数据。这不是一个坏方法,虽然我不会像他那样实现它。他/她的方式会大量消耗带宽和资源,因为你每隔几秒钟就会重新创建整个表格。简化为会话类型格式,他/她的方法如下:
Client -> Server - Send me the entire table.
Server -> Client - Here's a 1MB table.
Client -> Server - Send me the entire table.
Server -> Client - Here's an 1MB table.
Client -> Server - Send me the entire table.
Server -> Client - Here's a 1.5MB table.
Client -> Server - Send me the entire table.
Server -> Client - Here's a 1MB table.
相反,基于AJAX轮询的方法应如下所示:
3:30PM Client -> Server - The last data I have is from 3:30PM. Got anything new?
3:30PM Server -> Client - No.
3:31PM Client -> Server - The last data I have is from 3:30PM. Got anything new?
3:31PM Server -> Client - No.
3:32PM Client -> Server - The last data I have is from 3:31PM. Got anything new?
3:32PM Server -> Client - No.
3:33PM Client -> Server - The last data I have is from 3:32PM. Got anything new?
3:33PM Server -> Client - Yes, two new records. Here you go, 10KB.
3:34PM Client -> Server - The last data I have is from 3:33PM. Got anything new?
3:34PM Server -> Client - No.
使用更少的带宽。我不打算告诉你如何在代码中做到这一点,虽然理解它相对简单并代表了对deostroll方法的巨大改进。
相反,我想描述基于SignalR的方法是如何工作的。 SignalR是“实时”。它利用了几种技术将服务器的“推送”推送到客户端。用于实现此功能的一种技术称为Web套接字,这是首选方法。但如果客户端或服务器不具备Web套接字,SignalR可以优雅地切换到其他技术。你不必担心这一点,但这一切都得到了照顾。
让我们看一下在SignalR中实现它的简单方法。每次更改表数据时,都希望在客户端上运行JavaScript函数以使用最新数据更新它们。
首先,我们需要服务器上的集线器。
public class TableHub : Hub
{
}
在客户端,执行此操作以连接事件:
$(function () {
var tableHub= $.connection.tableHub;
tableHub.client.tableChanged= function (html) {
//append the html markup to your DOM
};
});
然后,只要表数据发生变化,请在服务器上调用此代码:
var context = GlobalHost.ConnectionManager.GetHubContext<TableHub >();
string html="<table><tr><td>Some data</td></tr></table>"; //obviously you'd built the HTML table up here
context.Clients.All.TableChanged(html); //call tableChanged() on the client!
实际上最终将在客户端调用tableChanged()
函数,并从服务器端启动它!这基本上是远程过程调用。因此,这不仅会考虑选择最佳的可用传输机制(Web socks,Server Sent Events,Long Polling),还会解析客户端功能,并允许您使用服务器端的dynamics
来调用它们。
这是一个非常基本的例子。我们正在为表格发送整个HTML,这并不理想。但是,通过一些工作,您可以通知客户端何时对API进行AJAX调用以仅检索已更改的表数据,而不是检索整个表。事实上,这是我最近创建的一个网站,用于实时将新文章从服务器推送到客户端。
答案 1 :(得分:1)
根据你的代表和个人资料,我不相信你会抓住这一切。如果你想知道为什么我们这样做,你真的需要探索。
你需要一些javascript的风格,如此处已有的答案所述。您需要对页面/通用处理程序(ashx)执行一些ajax调用以生成转发器标记。
有几种方法可以呈现控件(即转发器),但对于您的情况,最好使用usercontrol来完成该工作。这有一些挑战(虽然没有解释原因)。
以下是使用通用处理程序
单独执行此操作的一般方法 - 呈现用户控件public class refresh : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
FormlessPage page = new FormlessPage();
Control ctrl = page.LoadControl("~/RepeaterHoster.ascx");
StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
page.Controls.Add(ctrl);
page.RenderControl(hw);
context.Server.Execute(page, hw, false);
context.Response.Write(sw.ToString());
}
public bool IsReusable
{
get
{
return false;
}
}
}
你注意到我使用了无Formless页面。具体定义如下:
public class FormlessPage : Page
{
public override void VerifyRenderingInServerForm(Control control)
{
//keeping it empty
//base.VerifyRenderingInServerForm(control);
}
}
然后你的aspx页面看起来像这样:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApp.DynamicRepeater.WebForm1" %>
<%@ Register Src="RepeaterHoster.ascx" TagName="RepeaterHoster" TagPrefix="uc1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Repeater Refresh Demo</title>
<style>
#content {
border:1px dotted;
line-height:2em;
}
#content div {
background-color:#00ff90;
padding:3px;
display:inline;
margin:3px;
text-align:center;
}
</style>
<script src="Scripts/jquery-2.1.1.min.js"></script>
<script>
$(function () {
var content = $('#content');
setInterval(function () {
content.load('refresh.ashx');
}, 5000);
});
</script>
</head>
<body>
<h2>Repeater Refresh Demo</h2>
<form id="form1" runat="server">
<div id="content">
<%-- content here (in this div) refreshes every 5 seconds--%>
<uc1:RepeaterHoster ID="RepeaterHoster1" runat="server" />
</div>
</form>
</body>
</html>
出于说明目的,用户控件非常简单。我只是从db(northwind) - mdf文件中随机显示5个产品名称。它的代码背后没有什么重要的,因此省略了那个。
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="RepeaterHoster.ascx.cs" Inherits="WebApp.DynamicRepeater.RepeaterHoster" %>
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
<ItemTemplate>
<div>
<%# ((System.Data.DataRowView)Container.DataItem)[0] %>
</div>
</ItemTemplate>
</asp:Repeater>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindDB %>"
SelectCommand="SELECT TOP (5) ProductName FROM [Alphabetical list of products] ORDER BY NEWID()"></asp:SqlDataSource>
现在,为什么我们要做这一切呢?为什么不简单地使用转发器控件而不是用户控件?
好吧,如果你真的想知道,你真的想自己想出这一切。 :)
快乐的节目......
答案 2 :(得分:0)
setTimeout(functionName,milliseconds)将设置一个在{milliseconds}参数后运行的特定函数。
你可以在刷新函数结束时调用setTimeout(refreshFunction,60000)
你也可以使用方法__doPostBack('UpdatePanel1','');用该刷新方法更新面板。
所以你的代码可能如下:
function() RefreshPanelEveryMinuteLoop {
__doPostBack('UpdatePanel1', '');
setTimeout(RefreshPanelEveryMinuteLoop, 60000);
}