ScriptManager的功能之一就是處理頁面上局部更新,對於這點,我想大家都知道。但是他工作的原理到底是什麼呢,這個暫且不從正面來回答。
我們這樣想一下,目前能夠真正實現局部重新整理的就是js+xml+dom等編寫的ajax代碼,而ScriptManager竟然也能實現局部重新整理,必然是通過什麼手段最終轉化成了js等的ajax代碼。這種猜想我們從哪裡去驗證一下呢,且看下面。
1.下面引用了TerreyLee的例子,稍作改動後如下,沒有帶任何Ajax控制項
代碼
前台代碼:
<form id="form1" runat="server">
<div>
<asp:Calendar ID="Calendar1" runat="server"></asp:Calendar>
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true"
onselectedindexchanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem Value="0">==請選擇==</asp:ListItem>
<asp:ListItem Value="1">Red</asp:ListItem>
<asp:ListItem Value="2">Yellow</asp:ListItem>
<asp:ListItem Value="3">Green</asp:ListItem>
</asp:DropDownList>
</div>
</form>
後台代碼:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
Calendar1.DayStyle.BackColor = System.Drawing.Color.FromName(DropDownList1.SelectedItem.Text);
}
運行結果:
看到狀態列帶有重新整理進度條。
查看一下伺服器端返回的源檔案:
<!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><title> </title></head><body> <form name="form1" method="post" action="Default.aspx" id="form1"><div><input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" /><input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" /><input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" /><input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTkxMjIzNTI5NQ9kFgICAw9kFgICAw8QZGQWAWZkZJtbkkCYOre8ffrFCqW5LPWkPTtr" /></div> <script type="text/javascript"> //<![CDATA[var theForm = document.forms['form1'];if (!theForm) { theForm = document.form1;}function __doPostBack(eventTarget, eventArgument) { if (!theForm.onsubmit || (theForm.onsubmit() != false)) { theForm.__EVENTTARGET.value = eventTarget; theForm.__EVENTARGUMENT.value = eventArgument; theForm.submit(); }}//]]></script> <div> <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWMgLIi4jfDQLd2/zADgK38ereCQLa96nuBQLa94WJDQLa9/GkBgLa9+3fDwLa99l6Atr39cMFAtr34f4OApeUoIgLApeUnKMMApeUiN4FApeU5PkOApeU0JQGApeUzM8PApeUuGsCl5SUhggCl5TA7g4Cl5S8igYC8q3OkgEC8q26zgoC8q2W6QMC8q2ChAsC8q3+vwwC8q3q2gUC8q3G9Q4C8q2ykQYC8q3u+QQC8q3alAwC7brsvQ8C7brYWALturT0CQLtuqCvAQLtupzKCgLtuojlAwLtuuSACwLtutC7DALtuoyEAQLtuvi/CgLI04vIBQLI0+fjDgLI09OeBgLI08+5DwLI07tVAp3kj+UKAo2LpYsGApKLpYsGApOLpYsGApCLpYsGdr/l7ekdPMwRDZCnhQ2pPfOpOcI=" /></div> <div> <table id="Calendar1“>...</table> <select name="DropDownList1" onchange="javascript:setTimeout('__doPostBack(\'DropDownList1\',\'\')', 0)" id="DropDownList1"><option selected="selected" value="0">==請選擇==</option><option value="1">Red</option><option value="2">Yellow</option><option value="3">Green</option> </select> </div> </form></body></html>
日期控制項轉換成了table(綠色部分),下拉式清單轉換成了select標籤(紅色部分)等,所有的一切都轉換成了瀏覽器能解釋的html標記語言 沒有什麼特別的
2.下面是帶有ScriptManager控制項的例子
<form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <asp:Calendar ID="Calendar1" runat="server"></asp:Calendar> <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" onselectedindexchanged="DropDownList1_SelectedIndexChanged"> <asp:ListItem Value="0">==請選擇==</asp:ListItem> <asp:ListItem Value="1">Red</asp:ListItem> <asp:ListItem Value="2">Yellow</asp:ListItem> <asp:ListItem Value="3">Green</asp:ListItem> </asp:DropDownList> </div> </form>
沒什麼特別,只是添加了一個scriptManager,當然運行結果不會跟第一個執行個體有什麼區別,因為頁面內沒有可以讓ScriptManager局部更新的組件。
我們看一下伺服器返回的html代碼
<!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><title> </title></head><body> <form name="form1" method="post" action="Default.aspx" id="form1"><div><input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" /><input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" /><input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" /><input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE3MDQ3NDcyNDcPZBYCAgMPZBYCAgUPEGRkFgFmZGRJzKmEsYB5gVwYRx8dFV3x6MurTw==" /></div> <script type="text/javascript"> //<![CDATA[var theForm = document.forms['form1'];if (!theForm) { theForm = document.form1;}function __doPostBack(eventTarget, eventArgument) { if (!theForm.onsubmit || (theForm.onsubmit() != false)) { theForm.__EVENTTARGET.value = eventTarget; theForm.__EVENTARGUMENT.value = eventArgument; theForm.submit(); }}//]]></script> <script src="/AJAX/WebResource.axd?d=WpudyoSACkhJZI41rIr6Gw2&t=634172191729687500" type="text/javascript"></script> <script src="/AJAX/ScriptResource.axd?d=BRDs2LbU_LAg6ZAoegBg0A1ZmMB4Gl-EP20pmeKgxP1i7fAhHRAcUfOQW96vJTq8YX82ufeV_8av8uEdGjhLBt36ynpIinbuj4reqRYgPiw1&t=5ccefe3d" type="text/javascript"></script><script type="text/javascript"> //<![CDATA[if (typeof(Sys) === 'undefined') throw new Error('ASP.NET Ajax 用戶端架構未能載入。');//]]></script> <script src="/AJAX/ScriptResource.axd?d=BRDs2LbU_LAg6ZAoegBg0A1ZmMB4Gl-EP20pmeKgxP1i7fAhHRAcUfOQW96vJTq82Fnxq88VMyVxCirTmVquRfdErM4nM7jSYzP2oTAbs70SDfMUJ-ZIDBycHzaXmnVW0&t=5ccefe3d" type="text/javascript"></script><div> <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWMgLGvacPAt3b/MAOArfx6t4JAtr3qe4FAtr3hYkNAtr38aQGAtr37d8PAtr32XoC2vf1wwUC2vfh/g4Cl5SgiAsCl5ScowwCl5SI3gUCl5Tk+Q4Cl5TQlAYCl5TMzw8Cl5S4awKXlJSGCAKXlMDuDgKXlLyKBgLyrc6SAQLyrbrOCgLyrZbpAwLyrYKECwLyrf6/DALyreraBQLyrcb1DgLyrbKRBgLyre75BALyrdqUDALtuuy9DwLtuthYAu26tPQJAu26oK8BAu26nMoKAu26iOUDAu265IALAu260LsMAu26jIQBAu26+L8KAsjTi8gFAsjT5+MOAsjT054GAsjTz7kPAsjTu1UCneSP5QoCjYuliwYCkouliwYCk4uliwYCkIuliwbzSm3y5GzwZploQy1UEn46DjrBBg==" /></div> <div> <script type="text/javascript"> //<![CDATA[Sys.WebForms.PageRequestManager._initialize('ScriptManager1', document.getElementById('form1'));Sys.WebForms.PageRequestManager.getInstance()._updateControls([], [], [], 90);//]]></script> <select name="DropDownList1" onchange="javascript:setTimeout('__doPostBack(\'DropDownList1\',\'\')', 0)" id="DropDownList1"><option selected="selected" value="0">==請選擇==</option><option value="1">Red</option><option value="2">Yellow</option><option value="3">Green</option> </select> </div> <script type="text/javascript"> //<![CDATA[Sys.Application.initialize();//]]></script></form></body></html>
相對於第一個執行個體,添加了一些js引用和一些js代碼,尤其要注意加粗的地方,這裡實際就是我們能實現重新整理的重要部分。現在應該知道,為什麼只有ScriptManager不能實現局部重新整理了吧,因為在Sys.WebForms.PageRequestManager.getInstance()._updateControls([], [], [], 90)這句話中,沒有可更新的控制項。
可能到這裡,還是不太相信添加這些代碼就能實現局部重新整理啦,我們繼續往下看
3.帶有ScriptManager和UpdatePanel控制項的執行個體
<form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Calendar ID="Calendar1" runat="server"></asp:Calendar> <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" onselectedindexchanged="DropDownList1_SelectedIndexChanged"> <asp:ListItem Value="0">==請選擇==</asp:ListItem> <asp:ListItem Value="1">Red</asp:ListItem> <asp:ListItem Value="2">Yellow</asp:ListItem> <asp:ListItem Value="3">Green</asp:ListItem> </asp:DropDownList> </ContentTemplate> </asp:UpdatePanel> </div> </form>
這一步其實也沒做什麼,只是添加了UpdatePanel控制項。
運行結果:
注意狀態列可是無重新整理哦
看一下伺服器端返回的html代碼
<!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><title> </title></head><body> <form name="form1" method="post" action="Default.aspx" id="form1"><div><input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" /><input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" /><input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" /><input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE1OTA0NzEyNTMPZBYCAgMPZBYCAgMPZBYCZg9kFgICAw8QZGQWAWZkZNKOh9DNKQIiu+lJISv5z1xLDKNA" /></div> <script type="text/javascript"> //<![CDATA[var theForm = document.forms['form1'];if (!theForm) { theForm = document.form1;}function __doPostBack(eventTarget, eventArgument) { if (!theForm.onsubmit || (theForm.onsubmit() != false)) { theForm.__EVENTTARGET.value = eventTarget; theForm.__EVENTARGUMENT.value = eventArgument; theForm.submit(); }}//]]></script> <script src="/AJAX/WebResource.axd?d=WpudyoSACkhJZI41rIr6Gw2&t=634172191729687500" type="text/javascript"></script> <script src="/AJAX/ScriptResource.axd?d=BRDs2LbU_LAg6ZAoegBg0A1ZmMB4Gl-EP20pmeKgxP1i7fAhHRAcUfOQW96vJTq8YX82ufeV_8av8uEdGjhLBt36ynpIinbuj4reqRYgPiw1&t=5ccefe3d" type="text/javascript"></script><script type="text/javascript"> //<![CDATA[if (typeof(Sys) === 'undefined') throw new Error('ASP.NET Ajax 用戶端架構未能載入。');//]]></script> <script src="/AJAX/ScriptResource.axd?d=BRDs2LbU_LAg6ZAoegBg0A1ZmMB4Gl-EP20pmeKgxP1i7fAhHRAcUfOQW96vJTq82Fnxq88VMyVxCirTmVquRfdErM4nM7jSYzP2oTAbs70SDfMUJ-ZIDBycHzaXmnVW0&t=5ccefe3d" type="text/javascript"></script><div> <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWMgKmh4YaAt3b/MAOArfx6t4JAtr3qe4FAtr3hYkNAtr38aQGAtr37d8PAtr32XoC2vf1wwUC2vfh/g4Cl5SgiAsCl5ScowwCl5SI3gUCl5Tk+Q4Cl5TQlAYCl5TMzw8Cl5S4awKXlJSGCAKXlMDuDgKXlLyKBgLyrc6SAQLyrbrOCgLyrZbpAwLyrYKECwLyrf6/DALyreraBQLyrcb1DgLyrbKRBgLyre75BALyrdqUDALtuuy9DwLtuthYAu26tPQJAu26oK8BAu26nMoKAu26iOUDAu265IALAu260LsMAu26jIQBAu26+L8KAsjTi8gFAsjT5+MOAsjT054GAsjTz7kPAsjTu1UCneSP5QoCjYuliwYCkouliwYCk4uliwYCkIuliwYWM6Mt9LLccy445bZ7PABY3EeS5w==" /></div> <div> <script type="text/javascript"> //<![CDATA[Sys.WebForms.PageRequestManager._initialize('ScriptManager1', document.getElementById('form1'));Sys.WebForms.PageRequestManager.getInstance()._updateControls(['tUpdatePanel1'], [], [], 90);//]]></script> <div id="UpdatePanel1"> <select name="DropDownList1" onchange="javascript:setTimeout('__doPostBack(\'DropDownList1\',\'\')', 0)" id="DropDownList1"><option selected="selected" value="0">==請選擇==</option><option value="1">Red</option><option value="2">Yellow</option><option value="3">Green</option> </select> </div> </div> <script type="text/javascript"> //<![CDATA[Sys.Application.initialize();//]]></script></form></body></html>
相對於第二個執行個體的源碼,我們可以看到差距是在紅色的部分,多出了ScriptManager局部重新整理的控制項UpdatePanel1。
通過這三個執行個體呢,我們應該能夠理解,為什麼ScirptManager能夠實現局部重新整理了,關鍵還是引入了我們在源碼中看到的js代碼,真是這些代碼實現了ScirptManager控制項的局部重新整理功能。
也可參考http://www.cnblogs.com/pangxiaoliang/archive/2009/06/28/1512758.html 寫的也很詳細,很不錯。