使用 AJAX.NET Timer 和 UpdatePanel 实现延迟内容加载






4.48/5 (18投票s)
2007 年 6 月 5 日
4分钟阅读

147071

2009
本教程介绍如何在页面加载完成后再加载页面的某些部分。此示例使用 AJAX.NET Framework 中的 Timer 和 UpdatePanel 控件来加载内容。

引言
当使用像长时间运行的 Web 服务或来自外部 Web 源的 RSS Feed 等内容时,最好先加载页面的重要部分,然后再加载加载速度较慢的部分。此示例将演示如何在页面主体有机会加载后加载多个 RSS 标题块。在页面加载期间,会显示占位符以指示将要加载其他内容。页面加载完成后,将异步检索并显示占位符的内容。
通常,页面上会出现需要比页面其余部分加载更长时间的内容。在某些情况下,您可以使用缓存来帮助解决此问题,但这并不总是可行或唯一的选择。如果某些内容加载时间比正常情况长,则显示某种视觉反馈给用户非常重要,以便他们知道需要等待。从远程服务器检索信息、显示大量数据以及照片库是一些可以推迟加载特定内容区域的示例。
必备组件
此示例使用
- Microsoft .NET 2.0 Framework
- Microsoft AJAX.Net 1.0 Framework
- DmitryR 创建的 RSS Toolkit (包含在示例的Bin文件夹中)
- Visual Studio 2005 或 Web Developer 2005 Express Edition
创建用户控件
您可以在 ASPX 页面上完成所有这些工作,但在此示例中,我们将使用一个UserControl
。我选择创建一个消耗 RSS Feed 的UserControl
,这个控件的名称正如其名,叫做RSSFeed.ascx。该控件使用ASP:Timer
、ASP:UpdatePanel
和ASP:MultiView
控件来创建一个在页面加载后 1 毫秒加载的内容块。
用户控件源代码 (RSSFeed.ascx)
在UserControl
的源代码中,需要关注的关键区域是
ASP:Timer
的OnTick
事件 - 在页面加载后 1 毫秒触发 - 触发从 RSS Feed 加载 RSS 标题的例程ASP:UpdatePanel
使用 AJAX 将标题加载到内容块中,并在不刷新页面的情况下更改ASP:MultiView
ASP:MultiView
支持多种显示选项,具体取决于内容块所处的阶段,例如:默认、内容已加载、内容加载失败
<%@ Control Language="VB" AutoEventWireup="false"
CodeFile="RSSFeed.ascx.vb" Inherits="RSSFeed" %>
<%@ Register Assembly="RssToolkit" Namespace="RssToolkit" TagPrefix="cc1" %>
<%--
Create a datasource for the RSS feed. For this example, I have used the
RSS Toolkit to consume a RSS feed.
--%>
<cc1:RssDataSource ID="rssData" runat="server"
Url="http://tempuri.com"
MaxItems="5" />
<asp:Panel runat="server" ID="pnlRSS" CssClass="RSSBlock" Width="275">
<asp:Label runat="Server" ID="lblHeader" Text="Headlines" Visible="False" />
<asp:UpdatePanel runat="Server" ID="updateRSS" UpdateMode="Conditional">
<ContentTemplate>
<asp:MultiView runat="server" ID="mvRSS" ActiveViewIndex="0" >
<%-- This is the default view that will load with the page --%>
<asp:View runat="Server" ID="view1">
<asp:image runat="server" ID="image1"
ImageAlign="middle" ImageUrl="spinner.gif" />
<asp:Label runat="Server" ID="label1"
Text="Loading..." Font-Size="smaller" ForeColor="orange" />
</asp:View>
<%--
This is the where you will display the content that you want to
load AFTER the page loads. In this example, the RSS headlines
will be ret rived and displayed here.
--%>
<asp:View runat="server" ID="view2">
<asp:Repeater runat="Server" ID="rptRSS">
<HeaderTemplate>
<asp:Label runat="Server" id="lblRSSHeader"
Text='<%# lblHeader.Text %>'
Class="RSSHeader" />
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:hyperlink runat="server" ID="linkRSS"
Text='<%# Eval("Title") %>'
NavigateUrl='<%# Eval("Link") %>' />
</li>
</ItemTemplate>
<FooterTemplate></ul></FooterTemplate>
</asp:Repeater>
</asp:View>
<%-- This is displayed if the content fails to load --%>
<asp:View runat="Server" ID="view3">
<asp:Label runat="Server" ID="lblNoData"
Text="Unable to load headlines at this time."
Font-Size="smaller" ForeColor="orange" />
</asp:View>
</asp:MultiView>
<%--
The timer works in millisecond intervals. A setting of "1"
will begin loading the block almost instantly after the page loads.
--%>
<asp:Timer ID="timerRSS" Interval="1"
OnTick="DisplayRSS" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
用户控件代码隐藏 (RSSFeed.ascx.vb)
请注意以下关键区域
- 两个公共属性 URL 和 RSSTitle 将允许您将 RSS Feed 的 URL 和内容块的标题传递给
UserControl
。您将在后面的文章中看到如何实现这一点。 DisplayRSS
子程序通过ASP:Timer
的 OnTick 事件在达到其 Interval 时被触发。当然,您也可以轻松地做其他事情,例如显示长时间运行的 Web 服务的结果、大型数据表、大型图像、视频等。
Option Strict On
Option Explicit On
Imports System.Data
Imports System.Xml
Imports System.Net
Imports System.IO
Partial Class RSSFeed
Inherits System.Web.UI.UserControl
Public WriteOnly Property URL() As String
Set(ByVal value As String)
'Link to the RSS XML page
rssData.Url = value
End Set
End Property
Public WriteOnly Property RSSTitle() As String
Set(ByVal value As String)
'Create a header for the RSS block
lblHeader.Text = value
End Set
End Property
Protected Sub DisplayRSS(ByVal s As Object, ByVal e As EventArgs)
Try
'Download the RSS feed
Dim wc As WebClient
wc = New WebClient()
wc.Proxy.Credentials =
System.Net.CredentialCache.DefaultNetworkCredentials
Dim feed As Byte()
feed = wc.DownloadData(rssData.Url)
'Populate the RSS content block
rptRSS.DataSource = rssData
rptRSS.DataBind()
'Display the loaded content block
mvRSS.ActiveViewIndex = 1
Catch ex As Exception
'Display the "unable to load" content block
mvRSS.ActiveViewIndex = 2
End Try
'Important! Turn the timer off or it will continuously run
'this routine. You could add an increased value to the
'Interval setting if you want it to try again but, at some
'point you need to tell it to stop--unless you are purposefully
'cycling through content.
timerRSS.Enabled = False
End Sub
End Class
将用户控件添加到网页
在此示例中,多个 RSSFeedUserControl
实例已添加到Default.aspx以演示效果。大多数UserControl
都提供了有效的 RSS URL,但有些提供了无效或缺失的 URL,以展示内容无法正确加载时会发生的情况。RSS Feed 来自各种不同的 Web 源。以下是如何将UserControl
添加到网页的方法
在页面顶部,<%@ Page %>
指令之后
<%@ Register Src="RSSFeed.ascx" TagName="RSSFeed" TagPrefix="uc1" %>
在页面正文中
请注意,该控件正在接收我们之前创建的 RSSTitle 和 URL 属性的值。
<uc1:RSSFeed id="RSSFeed1" runat="server"
RSSTitle="MSDN: United States"
URL="http://msdn.microsoft.com/globalrss/en-us/global-msdn-en-us.xml" />
本地运行示例
- 下载示例文件 (VB | C#)
- 解压到本地文件夹
- 在 Web Developer Express 或 Visual Studio 2005 中将DelayedContentLoading文件夹打开为网站
- 生成并运行网站
关注点
- 使用多个带有计时器的
UserControl
时,它们将按顺序一个接一个地加载。这意味着第二个UserControl
将在第一个UserControl
加载后开始其计时器,依此类推。 - 块中的内容不是随页面一起加载的。因此,搜索引擎将不会索引页面加载后加载的内容块。查看在线示例的源代码以了解我的意思。
- 这些内容块可能会造成可访问性问题。由于它们未添加到页面源代码中,我不确定屏幕阅读器和其他辅助技术 (AT) 会如何响应。也许有人可以在下面的评论区提供一些反馈。
高级选项
通过为延迟内容创建一个UserControl
,我们现在拥有了一个可重用的控件,可以动态添加。因此,请考虑以下扩展此想法的选项
- 将多个
UserControl
实例加载到ASP:PlaceHolder
中,而不是在页面上手动逐个编写它们。 - 如果在
OnTick
事件触发后不停止ASP:Timer
,它会一直运行。如果您使用更长的间隔,例如 5000(5 秒),您可以让计时器运行并显示每 5 秒更改一次的内容块系列。
历史
- 2007 年 6 月 5 日 - 发布原始版本
- 2007 年 6 月 6 日 - 根据 nbr (Noel) 的建议更新,以支持代理。最初在DmitryR 的博客上提出
- 2007 年 10 月 24 日 - 添加了演示项目的 C# 版本 (感谢 Shawn N.!)