【问题标题】:how to refresh Repeater after 1 minute with javascript?1分钟后如何用javascript刷新Repeater?
【发布时间】:2014-10-29 04:29:39
【问题描述】:

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

【问题讨论】:

  • 不要将其视为“刷新中继器”。把它想象成刷新表,因为Repeater纯粹存在于服务器端,生成的标记在客户端。无论如何,许多人开始回避“不断轮询服务器以获取更新”,转而使用新技术将更新从服务器推送到客户端。在 .NET 堆栈中,用于此的技术是 SignalR。您会发现 SignalR 比不断轮询服务器要好得多,从而减轻了客户端、带宽和服务器资源的压力。

标签: javascript c# asp.net .net webforms


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 或者我应该说,在这里做你想做的事情是极其不平凡的。
  • 我必须把更新面板放在哪里?在中继器之前还是在中继器内部?
  • @CBauer 不需要 UpdatePanel 来完成此操作,并且经常会引入新问题。对于这种情况,我不建议使用更新面板。如果我这样做了,我会使用计时器而不是手动使用 JS 进行回发。
  • @mason 考虑到 OP 试图做什么,以及对这样做的选项缺乏熟悉,我非常怀疑 OP 是否可以轻松处理更复杂的事情。看看 deostroll 的回答,这对于 OP 来说将是一场无法维持的噩梦。这是 3 行代码和一个 asp.net 控件。和 SignalR?祝你好运。对控件进行部分刷新的更新面板有什么问题?这正是 OP 想要的,不会引入任何额外的复杂性。
  • 就像我说的那样,如果您希望 UpdatePanel 在间隔内回发,则应该使用 Timer 而不是计划 JavaScript。 SignalR 非常简单。也许你不熟悉它,但这并不意味着它不是一个简单的解决方案。 UpdatePanel 似乎是一个不错的选择,但随后您实施它们并遇到各种问题。对于使用 AJAX 和适当的 Web 服务的实际用途而言,它们是一种糟糕的抽象。正如 OP 中所述,他希望避免使用 UpdatePanel 以减少服务器的压力。
【解决方案2】:

根据您的代表和个人资料,我认为您不会这么快就掌握了所有内容。如果您想知道我们为什么这样做,您真的需要探索。

您需要一些这里的答案中提到的样式的 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;
        }
    }
}

您会注意到我使用了 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>

现在,我们究竟为什么要做这一切?为什么不简单地使用转发器控件而不是用户控件?

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

编程愉快...

【讨论】:

    【解决方案3】:

    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、服务器发送事件、长轮询),而且还解决了客户端函数,并允许您在服务器端使用 dynamics 调用它们。

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

    【讨论】:

    • 第二个代码块是放在 tablehub 内部,还是放在带有某种计时器的函数中?
    • 这将进入您页面的 JavaScript(它使用 jQuery)。请注意,您还必须将 SignalR 添加到您的项目中,并在您的页面上嵌入适当的 SignalR 脚本(我的答案的第一个链接中的示例)。请注意,我没有给出完整的示例,也没有告诉您如何在项目中嵌入 SignalR 脚本(很简单)或映射 SignalR(也很简单),以及您放置第 3 个代码块的位置取决于您的源数据可能会更改。我知道这需要一些范式转变,但我真的认为如果你决定实施它会改善你的应用程序
    • 您好,谢谢您的回答。我很清楚这一点。但是我可以把我的中继器放在哪里?我必须在哪里创建集线器?你能详细指导我吗?
    • 或为此提供任何示例参考。
    • @Deepak 您将转发器放在通常放置的位置 - 在 .aspx 页面上。如果您想要清晰的示例,请查看我在答案中添加的第一个链接。他们有一个很好的例子可以帮助你开始使用 SignalR。
    猜你喜欢
    • 1970-01-01
    • 2019-02-28
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多