在我接触ajax.net前,update panel的大名已经是如雷贯耳了。update panel到底如何实现partial render的呢,半年来一直塞在我的思绪中。
一个星期前,终于开始了我的ajax.net之旅,美妙绝伦的js 扩展令人陶醉。但不幸的是在我以updatepanel
machinism,inside updatepanel ajax等等等为关键字
google,baidu后依然没有任何斩获,大多数搜到的条目都是告诉你如何往updatepanel里面拖控件的。我也知道博客园众多高人,其中老赵
同志最为显目,我翻了他的很多文章,都没能打开我的心结。(可能他写过相关文章,我没找到。)
没办法,只好用reflector打开程序集,我努力的寻找,寻找那个方法,那个能改变呈现流程的方法。终于我找到了你----------- SetRenderMethodDelegate。
以下代码模拟了update panel的partial render行为。
ParialRender.aspx.cs
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->usingSystem;
usingSystem.Data;
usingSystem.Configuration;
usingSystem.Collections;
usingSystem.Web;
usingSystem.Web.Security;
usingSystem.Web.UI;
usingSystem.Web.UI.WebControls;
usingSystem.Web.UI.WebControls.WebParts;
usingSystem.Web.UI.HtmlControls;
usingSystem.Collections.Specialized;
publicpartialclassPartialRender:System.Web.UI.Page
{
privatestaticRandomrandom=newRandom();
protectedvoidPage_Load(objectsender,EventArgse)
{
NameValueCollectionheaders=this.Request.Headers;
//识别异步回调
if(headers["x-myajax"]!=null)
{
this.SetRenderMethodDelegate(this.MyAjaxPageRender);
this.form1.SetRenderMethodDelegate(this.MyAjaxFormRender);
}
}
//改变页面的呈现流程
privatevoidMyAjaxPageRender(HtmlTextWriterwriter,Controlpage)
{
this.form1.RenderControl(writer);
}
//改变form的呈现流程
privatevoidMyAjaxFormRender(HtmlTextWriterwriter,Controlpage)
{
this.UpdatePanel.RenderControl(writer);
}
protectedvoidbtnSubmit_Click(objectsender,EventArgse)
{
this.txtRandomNumber.Text=random.Next(1000).ToString();
}
}
PartialRender.aspx
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><%@PageLanguage="C#"AutoEventWireup="true"CodeFile="PartialRender.aspx.cs"Inherits="PartialRender"%>
<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<headrunat="server">
<title>浅析updatepanel之partialrender原理</title>
<script>
varxmlHttp;
//创建xmlhttprequest对象
functioncreateXMLHttpRequest(){
if(window.ActiveXObject)
{
returnnewActiveXObject("Microsoft.XMLHTTP");
}
elseif(window.XMLHttpRequest){
returnnewXMLHttpRequest();
}
else{
returnnull;
}
}
//状态改变handle
functionhandleStateChange(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
processCallback();
}
}
}
//处理异步回调
functionprocessCallback(){
parseDom(xmlHttp.responseText);
}
//发出异步请求
functiondoRequest(){
xmlHttp=createXMLHttpRequest();
varurl=window.location.href;
xmlHttp.open("POST",url,true);
xmlHttp.onreadystatechange=handleStateChange;
//标记异步回调
xmlHttp.setRequestHeader("x-myajax","nothing");
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
varqueryString=createQueryString();
xmlHttp.send(queryString);
}
//创建querystring,也就是模拟表单里面的name-value对。
functioncreateQueryString(){
varresult="btnSubmit=";
result+="&txtRandomNumber="+document.getElementById("txtRandomNumber").value;
parseDom(document.forms[0].outerHTML);
for(vari=0;i<hiddenFields.length/2;i++)
{
varhiddenField=document.getElementById(hiddenFields[i*2]);
result+="&"+encodeURIComponent(hiddenField.name)+"="+encodeURIComponent(hiddenField.value);
}
returnresult;
}
//这里存放隐藏字段的id和value,隐藏字段就是__VIEWSTATE之类的东西
varhiddenFields=null;
//updatePanel内部的html
varupdatePanelContent=null;
//分析一段html,求出它里面<inputtype=hidden>和updatepanel
functionparseDom(text){
hiddenFields=[];
updatePanelContent="";
varroot=document.createElement("span");
root.innerHTML=text;
parseNode(root);
for(vari=0;i<hiddenFields.length/2;i++){
document.getElementById(hiddenFields[i*2]).value=hiddenFields[i*2+1];
}
document.getElementById("UpdatePanel").innerHTML=updatePanelContent;
}
//递归分析节点
functionparseNode(node){
if(node.nodeType==3){
return;
}
if(node.tagName.toLowerCase()=="input"&&node.type.toLowerCase()=="hidden"){
hiddenFields.push(node.id);
hiddenFields.push(node.value);
return;
}
if(node.id=="UpdatePanel"){
updatePanelContent=node.innerHTML;
return;
}
for(vari=0;i<node.childNodes.length;i++){
parseNode(node.childNodes[i]);
}
}
</script>
</head>
<body>
<formid="form1"runat="server">
<asp:PanelID="UpdatePanel"runat="server">
<asp:ButtonID="btnSubmit"runat="server"Text="生成随机数"OnClick="btnSubmit_Click"OnClientClick="doRequest();returnfalse;"/>
<asp:TextBoxID="txtRandomNumber"runat="server"></asp:TextBox>
</asp:Panel>
</form>
</body>
</html>
代码在普通的panel中放了一个button,一个textbox,按button就能无刷新的产生随机数。
1.要改变submit的行为,原来的表单不能提交了,而是交给xmlhttprequest提交。
2.服务器端要知道是xmlhttprequest做的请求还是普通的请求,这个通过设置一个自定义的http头实现 x-myajax.
3.要改变服务器端的呈现流程,原来呈现整个页面,但异步请求的时候只能
呈现updatepanel和一些系统级别的东西(__VIEWSTATE之类).我们通过Control的SetRenderMethodDelegate方法来实现。
4.要能解析response text, 根据解析的结果设置__VIEWSTATE的值,设置updatepanel内部的html。
这只是一个简单的模拟,实际中updatepanel,scriptmanager的行为复杂得多,比如说trigger,focus等等。
分享到:
相关推荐
updatepanel的使用方法及实例,其中有updatepanel的嵌套使用。
Ajax控件:UPdatepanel使用
scriptManager和updatepanel.docscriptManager和updatepanel.doc
UpdatePanel完整例子 UpdatePanel完整例子
关于updatepanel控件的使用。
详细介绍了updatepanel控件的各种使用方法。
UpdatePanel的简单用法: 局部更新是ajax技术的最基本,也是最重要的用法,今天大概把asp.net ajax中的局部更新控件 updatepanel的用法记录下,大家可以共同探讨
关于UpdatePanel的各种跳转,包括有刷新跳转、无刷新跳转,以及在UPDATEPANEL下的跳转
关于UpdatePanel控件的使用和详解,没接触过这个控件的人可以拿做参考.该文件为Word格式,是一片文章的word版,属于转载.
AJAX UpdatePanel 加载等待提示框
ASP.NET_AJAX入门系列:使用UpdatePanel控件.docASP.NET_AJAX入门系列:使用UpdatePanel控件.doc
ASP.NET AJAX入门系列UpdatePanel控件教程
UpdatePanel 无刷新时如何显示js效果
提供免费下载 Timer控件定时更新UpdatePanel - DemoVS2010版.zip
用UpdatePanel异步展开GridView行数据,欢迎下载!
并不是所有的Web浏览器都支持UpdatePanel,因此而检 测。
UpdatePanel和Jquery冲突的解决方法,挺实用的,解决了自己的很大问题。
一个进行ASP.NET 的UpdatePanel回传错误处理程序定制化操作代码例子。
客户端动态的弹出模态窗口,可以加javascript验证
直接使用FileUpload,服务端是无法找到上传文件的。updatepanel中不能使用fileupload的弥补方法[IFrame方式]