UpdatePanel的妙用:Incremental Content

   Incremental Content是我随意取的名字,我有时候会希望,把一些常见的场景,总结出ASP.NET AJAX一些比较固定的使用模式。Incremental Content是我为现在这个“模式”取的名字。这个模式的作用,就是使用UpdatePanel来不断地在页面上增加内容。

  想到这个使用方式的原因,是因为在中午与Bing对UpdatePanel的一些问题进行了讨论。他谈到,使用UpdatePanel,会造成过多的数据传输上的浪费。例如博客园的回复,事实上要更新的只是新增的内容,而并不需要整个评论区进行刷新。

  是啊,说的没错。我当时的回答是:“这是因 为UpdatePanel的设计初衷,可以很方便地为页面带入AJAX效果”。但是这并不能为UpdatePanel带来的这个问题进行开脱。不过在我简 单进行了思考之后,发现要让UpdatePanel支持内容的递增效果并不困难。我们只要灵活地运用UpdatePanel的工作机制即可。

  UpdatePanel在更新时,最后从服 务器端得到的是什么呢?事实上得到的是需要更新的UpdatePanel的ID,以及UpdatePanel中的内容。接下去作的事情自然不必多说,即使 通过ID找到UpdatePanel所在的div(或者span),然后替换其innerHTML。

  等等,有没有想到什么?客户端是如何找到需 要更新的UpdatePanel?“通过ID”。既然是通过ID,我们为什么不能让UpdatePanel更新到我们指定的区域呢?我们当然可以这么做, 下面的示例就是这样实现UpdatePanel的Incremental Content的。

  首先,在页面上放置一个UpdatePanel,在它的ContentTemplate中,我们使用一个Visible为False的Panel来包装了内容,它的作用,可以说是为了给每次添加的内容设定一个模版。如下:

Default.aspx
<div id="inputContainer">
<asp:UpdatePanel ID="upAppendContent" runat="server">
<ContentTemplate>
<strong>
您在<asp:Literal runat="server" ID="time" />输入了:
</strong>
<br />
<asp:Literal runat="server" ID="appendMessage"></asp:Literal>
<hr />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnAppend" />
</Triggers>
</asp:UpdatePanel>
</div>

<br /><br />

<asp:TextBox ID="txtAppendMessage" runat="server"></asp:TextBox>
<asp:Button ID="btnAppend" runat="server" Text="btnAppend" OnClick="btnAppend_Click" />

 

  然后,我们在每次用户点击按钮之后,我们需 要将UpdatePanel中的控件内容进行修改。请注意,在Form_Load方法中,需要在非异步刷新的情况下,将UpdatePanel中的内容清 空,这样避免了在第一次加载页面时UpdatePanel中出现内容。如下:

Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!ScriptManager.GetCurrent(this).IsInAsyncPostBack)
{
this.upAppendContent.ContentTemplateContainer.Controls.Clear();
}
}

protected void btnAppend_Click(object sender, EventArgs e)
{
this.time.Text = DateTime.Now.ToString("HHʱmm·ÖssÃë");
this.appendMessage.Text = HttpUtility.HtmlEncode(this.txtAppendMessage.Text);
}

 

  如果到这里为止,相信大家能够猜到执行的效果是怎么样的:每次提交后,UpdatePanel中的信息被更改。这并不是我们需要的Incremental Content的效果。因此,我们还需要加一些JavaScript进行辅助。如下:

Default.aspx
<script type="text/javascript" language="javascript">
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function(sender, e)
{
var upID = "<%= this.upAppendContent.ClientID %>";
var refreshedPanels = e.get_panelsUpdated();

for (var i = 0; i < refreshedPanels.length; i++)
{
if (refreshedPanels[i].id == upID)
{
refreshedPanels[i].id = upID + Math.floor(9999 * Math.random());

var div = document.createElement("div");
div.id = upID;
$get("inputContainer").appendChild(div);
return;
}
}
});
</script>

 

  这段代码才是Incremental Content的关键所在。这这段代码中,我们响应了客户端的pageLoaded事件,也就是说,我们在UpdatePanel更新完毕之后,对于刷新 的UpdatePanel进行遍历。如果发现我们的目标UpdatePanel被更新了,则改变其ID,并新建一个div容器,添加到页面中合适的地方。 这样,UpdatePanel在下次进行更新时,就会将我们新建的容器作为客户端的UpdatePanel,并为其设置innerHTML。

  这就是Incremental Content。我们可以看到,服务器端每次回传的数据,只会是我们新增的内容,而我们每次提交的内容,都会被保留在页面上。如下:

Incremental Content

 

  Incremental Content的好处是什么呢?减少数据传输量是一方面。另外,如果使用Incremental Content,一般来说查询数据库的次数就能减少,这样就可以进一步降低资源消耗。

 

点击这里下载代码。

点击这里查看效果。

 

PS:

  建议博客园能够使用Incremental Content方法。由于博客园存在“刷新全部评论”的操作,所以可以使用UpdatePanel嵌套的方式,对内UpdatePanel使用 Incremental Content,而刷新全部评论时,则可以调用外部UpdatePanel的Update方法(或通过Trigger指定)。不过一旦使用了 Incremental Content方法,在“修改评论”和“删除评论”两个功能上,可能就要改变实现方式了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值