如何用javascript在1分钟后刷新Repeater

how to refresh Repeater after 1 minute with javascript?

本文关键字:刷新 Repeater 1分钟 何用 javascript      更新时间:2023-09-26

我已经创建了一个中继器,现在我想在每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实现这一点呢?

SignalR的创建正是为了解决您所描述的问题。

以下是您的情况:你想要一种显示信息的方式,这种信息可能会不断变化。在任何时候,都应该显示最新的信息。

以Web表单为中心的方法是使用UpdatePanel。但我和其他一些人并不喜欢这些。它们通常会在以后的道路上造成问题,因为它们不能很好地利用其他技术。它们也很"昂贵",在客户端和服务器之间来回发送大量数据,占用带宽和资源。

另一种方法是使用AJAX定期轮询服务器以获取数据,这在一定程度上受到了deoswalk的影响。这不是一个糟糕的方法,尽管我不会像他那样实施它。他/她的方式会极大地消耗带宽和资源,因为你每隔几秒钟就会重新创建整个表。归根结底,他/她的方法是这样的:

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.

这占用的带宽要少得多。我不想麻烦你在代码中展示如何做到这一点,尽管我知道它相对简单,并且代表着对deoswalk方法的巨大改进。

相反,我想描述基于SignalR的方法是如何工作的。SignalR是"实时"的。它利用了几种将更改从服务器"推送"到客户端的技术。用于实现此功能的一种技术称为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()函数,并从服务器端启动它!这基本上就是远程过程调用。因此,这不仅要考虑选择最佳可用的传输机制(网络袜、服务器发送事件、长轮询),而且还可以解析客户端功能,并允许您在服务器端使用dynamics调用它们。

这是一个非常基本的例子。我们正在发送下表的整个HTML,这并不理想。但是,只要做一点工作,就可以通知客户端何时对API进行AJAX调用,只检索更改后的表数据,而不是检索整个表。事实上,这是我在最近创建的一个网站上采用的一种方法,用于将新文章从服务器实时推送到客户端。

根据你的代表和个人资料,我不相信你会这么快抓住所有这些。如果你想知道我们为什么这样做,你真的需要探索。

您需要一些javascript的风格,正如这里已经提到的答案。您需要对页面/通用处理程序(ashx)进行一些ajax调用,以生成中继器标记。

有几种方法可以呈现控件(即中继器),但就您的情况而言,最好使用用户控件来完成这项工作。这也带来了一些挑战(但无法解释原因)。

以下是使用通用处理程序单独实现这一点的通用方法——呈现用户控件

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;
        }
    }
}

你会注意到我使用了无表单页面。其定义如下:

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>

现在,我们为什么要这么做?为什么不简单地使用中继器控件而不是用户控件呢?

好吧,如果你真的想知道,你真的很想自己弄清楚这一切。:)

快乐编程。。。

setTimeout(functionName,毫秒)将设置一个特定函数在{毫秒}参数之后运行。

在刷新函数结束时,您可以调用setTimeout(refreshFunction,60000)

您也可以使用方法__doPostBack('UpdatePanel1','');以该刷新方法更新面板。

所以你的代码可能看起来像:

function() RefreshPanelEveryMinuteLoop {
    __doPostBack('UpdatePanel1', '');
    setTimeout(RefreshPanelEveryMinuteLoop, 60000);
}