UpdatePanel这个缺点主要是因为他的更新机制造成的,UpdatePanel在更新时会把包含其中的内容全部提交,如果我们动态向UpdatePanel中添加内容,那么随着内容的增加,UpdatePanel提交的信息量将不断的增长,虽然仍是异步提交,但是却违背了ajax减少数据传输量的初衷;当动态添加的信息量过大,以至于页面上的其他信息都可以被忽略不计时,这个缺点将是致命的,好在前辈们找到了解决的方案,下面我来总结一下:
先说说思路,其实主要思路就是欺骗,欺骗谁呢?我反复体会了一下,我认为这个方案欺骗的就是asp.net,我们可以在异步提交完成之前把真正发生刷新的UpdatePanel的id改变成其他任意名称,然后在它的下面添加一个新的<div></div>,把这个div的id设置为真正发生刷新的UpdatePanel原来的id,这样asp.net会按照这个id找到新建的这个div,并把更新内容填充进去,至此我们就完成了一个骗子的角色,因为我们欺骗的是微软的asp.net,所以一旦成功应该会很有成就感,大家想体会一下吗?具体的代码明天可能会写的
这是昨天没给出的代码,包括三个文件,其中的Site.master文件的代码如下:
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Site.master.cs" Inherits="Site" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns=" http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body style="font-size:11pt; font-family:Verdana;">
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" ScriptMode="Debug">
</asp:ScriptManager>
<div>
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
</asp:contentplaceholder>
</div>
<div id="message" style="color:Red;"></div>
<script language="javascript" type="text/javascript">
var timeoutSeed = null;
function showMessage(message, timeout)
{
$get("message").innerHTML = message;
if (timeoutSeed)
{
window.clearTimeout(timeoutSeed);
}
timeoutSeed = window.setTimeout(
function(){ $get("message").innerHTML = ""; },
timeout || 2500);
}
</script>
</form>
</body>
</html>
_4_IncrementalContent.aspx文件代码:
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="4_IncrementalContent.aspx.cs" Inherits="_4_IncrementalContent" Title="IncrementalContent" EnableViewState="false"%>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<strong>Comment:</strong>
<div id="commentContainer">
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<%# (Container.DataItem as Comment).Content %>
<i><%# (Container.DataItem as Comment).Time %></i>
<hr />
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" />
</Triggers>
</asp:UpdatePanel>
</div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Add Comment" OnClick="Button1_Click" />
<script language="javascript" type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(
function(sender, e)
{
var upId = "<%= this.UpdatePanel1.ClientID %>";
var refreshedPanels = e.get_panelsUpdated();
for (var i = 0; i < refreshedPanels.length; i++)
{
if (refreshedPanels.id == upId)
{
refreshedPanels.id = upId + Math.floor(9999 * Math.random());
var div = document.createElement("div");
div.id = upId;
$get("commentContainer").appendChild(div);
return;
}
}
});
</script>
</asp:Content>
_4_IncrementalContent.aspx.cs文件代码如下:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
public partial class _4_IncrementalContent : System.Web.UI.Page
{
private static List<Comment> Comments;
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
// 在第一次打开页面时清空所有Comments。
// 古怪的用法,仅在这个示例时这么用。
Comments = new List<Comment>();
this.BindComments();
}
}
private void BindComments()
{
this.Repeater1.DataSource = Comments;
this.Repeater1.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
Comment comment = new Comment();
comment.Content = this.TextBox1.Text;
comment.Time = DateTime.Now;
// Comments.Add(comment);
this.Repeater1.DataSource = new Comment[] { comment };
// this.BindComments();
this.Repeater1.DataBind();
}
}
先说说思路,其实主要思路就是欺骗,欺骗谁呢?我反复体会了一下,我认为这个方案欺骗的就是asp.net,我们可以在异步提交完成之前把真正发生刷新的UpdatePanel的id改变成其他任意名称,然后在它的下面添加一个新的<div></div>,把这个div的id设置为真正发生刷新的UpdatePanel原来的id,这样asp.net会按照这个id找到新建的这个div,并把更新内容填充进去,至此我们就完成了一个骗子的角色,因为我们欺骗的是微软的asp.net,所以一旦成功应该会很有成就感,大家想体会一下吗?具体的代码明天可能会写的
这是昨天没给出的代码,包括三个文件,其中的Site.master文件的代码如下:
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Site.master.cs" Inherits="Site" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns=" http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body style="font-size:11pt; font-family:Verdana;">
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" ScriptMode="Debug">
</asp:ScriptManager>
<div>
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
</asp:contentplaceholder>
</div>
<div id="message" style="color:Red;"></div>
<script language="javascript" type="text/javascript">
var timeoutSeed = null;
function showMessage(message, timeout)
{
$get("message").innerHTML = message;
if (timeoutSeed)
{
window.clearTimeout(timeoutSeed);
}
timeoutSeed = window.setTimeout(
function(){ $get("message").innerHTML = ""; },
timeout || 2500);
}
</script>
</form>
</body>
</html>
_4_IncrementalContent.aspx文件代码:
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="4_IncrementalContent.aspx.cs" Inherits="_4_IncrementalContent" Title="IncrementalContent" EnableViewState="false"%>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<strong>Comment:</strong>
<div id="commentContainer">
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<%# (Container.DataItem as Comment).Content %>
<i><%# (Container.DataItem as Comment).Time %></i>
<hr />
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" />
</Triggers>
</asp:UpdatePanel>
</div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Add Comment" OnClick="Button1_Click" />
<script language="javascript" type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(
function(sender, e)
{
var upId = "<%= this.UpdatePanel1.ClientID %>";
var refreshedPanels = e.get_panelsUpdated();
for (var i = 0; i < refreshedPanels.length; i++)
{
if (refreshedPanels.id == upId)
{
refreshedPanels.id = upId + Math.floor(9999 * Math.random());
var div = document.createElement("div");
div.id = upId;
$get("commentContainer").appendChild(div);
return;
}
}
});
</script>
</asp:Content>
_4_IncrementalContent.aspx.cs文件代码如下:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
public partial class _4_IncrementalContent : System.Web.UI.Page
{
private static List<Comment> Comments;
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
// 在第一次打开页面时清空所有Comments。
// 古怪的用法,仅在这个示例时这么用。
Comments = new List<Comment>();
this.BindComments();
}
}
private void BindComments()
{
this.Repeater1.DataSource = Comments;
this.Repeater1.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
Comment comment = new Comment();
comment.Content = this.TextBox1.Text;
comment.Time = DateTime.Now;
// Comments.Add(comment);
this.Repeater1.DataSource = new Comment[] { comment };
// this.BindComments();
this.Repeater1.DataBind();
}
}