閱讀本文之前,您需要安裝完成Microsoft ASP.NET AJAX v1.0 Beta(詳見擁抱變化——從Atlas到ASP.NET AJAX(1):下載安裝總覽)。安裝完成之後,Visual Studio中建立Web Site的時候會多出一個模版:ASP.NET AJAX Enabled Web Site。接下來的內容均將基於建立的ASP.NET AJAX Enabled Web Site。
在ASP.NET AJAX中,相對於ScriptManager翻天覆地的變化,UpdatePanel的變化要“友善”得多,也較為易於理解。UpdatePanel將仍作為最重要ASP.NET AJAX伺服器端控制項存在於ASP.NET AJAX核心組件(Microsoft ASP.NET AJAX v1.0 Beta)中,用於讓頁面中的某個局部內容擁有非同步更新的功能。
本文將分析相對於Atlas,ASP.NET AJAX中UpdatePanel控制項使用方法的變化。
ScriptManager的設定
和Atlas一樣,ScriptManager的EnablePartialRendering屬性也要設定為true,但這已經是ASP.NET AJAX中的預設設定,我們一般無須再手工幹預。另外,ASP.NET AJAX中的ScriptManager還暴露出了AsyncPostBackErrorMessage屬性、AsyncPostBackTimeout屬性和AsyncPostBackError事件,可以用於對UpdatePanel在進行非同步更新時引發的異常進行處理。這部分內容詳見擁抱變化——從Atlas到ASP.NET AJAX(2):變化得翻天覆地的ScriptManager(Dflying仍有好多疑問,請指教)。
讓我們從聲明UpdatePanel的標籤開始逐一說明其變化:
<asp:UpdatePanel>標籤
同樣,原有的“altas”首碼被改為了“asp”。下面是UpdatePanel支援的幾個屬性:
- RenderMode:與原有的Atlas ScriptManager完全相同,表示UpdatePanel最終呈現的HTML元素。Block(預設)表示<div>,Inline表示<span>,按布局需求選擇即可。
- UpdateMode:與原有的Atlas ScriptManager基本相同,表示UpdatePanel的更新模式。可選Always或Conditional。Always(預設)表示無論任何類型(非同步回送或整頁回送),任何控制項引發的回送均將更新該UpdatePanel。Conditional表示只有當前UpdatePanel的Trigger,或ChildrenAsTriggers屬性為true時當前UpdatePanel中控制項引發的非同步回送,以及整頁回送,或是伺服器端調用Update()方法才會引發更新該UpdatePanel。
- ChildrenAsTriggers:布爾值(預設為true)新屬性,表示當UpdateMode屬性為Conditional時,該UpdatePanel中包含的控制項所引發的非同步回送是否會觸發本UpdatePanel的更新。需要注意的是,當UpdateMode為Always時,ChildrenAsTriggers不能設定為false,否則頁面將拋出異常。
接下來讓我們看看<asp:UpdatePanel>標籤中的各種子標籤的變化:
<Triggers>標籤
<Triggers>中同樣將設定該UpdatePanel的觸發器集合。在Atlas的UpdatePanel中,支援ControlValueTrigger和ControlEventTrigger兩種觸發器,ASP.NET AJAX的UpdatePanel則將二者統一為AsyncPostBackTrigger,另外還添加了另外一種觸發器——PostBackTrigger。詳細說明如下:
<asp:AsyncPostBackTrigger>標籤
AsyncPostBackTrigger用來指定某個伺服器端控制項以及其將觸發的伺服器端事件作為該UpdatePanel的非同步更新觸發器,類似於Atlas中的ControlEventTrigger。AsyncPostBackTrigger支援如下兩個屬性:
- ControlID:伺服器端控制項的ID。
- EventName:伺服器端控制項的某個伺服器端事件。
<asp:PostBackTrigger>標籤
在Atlas的UpdatePanel中,其包圍的控制項所引發的回送均將被強制使用非同步回送模型。ASP.NET AJAX中PostBackTrigger的出現則彌補了這個缺陷,給開發人員更大的靈活性。PostBackTrigger可以指向本UpdatePanel中包含的某個伺服器端控制項,這樣由該控制項引發的回送將仍使用傳統的整頁回送模型。PostBackTrigger支援如下屬性:
- ControlID:<ContentTemplate>中某個將引發整頁回送的伺服器端控制項的ID。
<ContentTemplate>標籤
與Atlas的UpdatePanel中的<ContentTemplate>完全相同,用來放置需要進行非同步更新的局部頁面內容。
非同步回送和整頁回送
所謂“整頁回送”,是指傳統的HTTP POST過程,頁面內容將在回送之後完全重新整理。所謂“非同步回送”,即回送將通過XmlHTTPRequest對象非同步進行,頁面內容將仍能夠得以保留。
預設情況下,ASP.NET中所有的回送均為整頁回送。但使用了UpdatePanel之後,處於如下情況的控制項的回送將改為非同步進行:
- 在UpdatePanel之外,被<asp:AsyncPostBackTrigger>引用,作為某個UpdatePanel進行非同步更新的觸發器的控制項。
- 在UpdatePanel中,未被該UpdatePanel的<asp:PostBackTrigger>引用的伺服器端控制項。
相對於Atlas,ASP.NET AJAX中的非同步回送還增加了若干個用戶端的事件,讓用戶端也擁有了類似伺服器端Web Form生存周期的概念。這是通過配合用戶端PageRequestManager對象來實現的。
PageRequestManager對象暴露出如下若干個事件,提供給我們充分的可自定發揮空間:
- initializeRequest:在該事件的處理函數中,我們可以進行一些額外的、在將請求發送回伺服器端之前的附加任務,例如取消即將發出的非同步請求、修改某個將要發送回伺服器的參數資訊等。該事件的參數為InitializeRequestEventArgs。
- beginRequest:非同步請求即將發送時觸發的事件,在該事件的處理函數中,我們可以顯示出某段提示更新的資訊(UpdateProgress控制項)。該事件的參數為BeginRequestEventArgs。
- pageLoding:非同步請求進行中時觸發的事件,在該事件的處理函數中,我們可以為UpdatePanel即將到來的更新進行一些準備,例如釋放使用過的資源等。同樣在該事件的處理函數中我們還可以及檢查伺服器端發送過來的狀態資訊,並根據不同的狀態完成相應的操作控制。該事件的參數為PageLoadingEventArgs。
- pageLoaded:非同步請求返回時觸發的事件,在該事件的處理函數中,我們可以訪問到更新完成後UpdatePanel中新的內容。該事件的參數為PageLoadedEventArgs。
- endRequest:非同步請求完成時觸發的事件,在該事件的處理函數中,我們可以顯示更新中可能遇到的異常資訊、隱藏UpdateProgress控制項、或是其他一些什麼別的附加操作等。該事件的參數為EndRequestEventArgs。
UpdatePanel的更新策略
ASP.NET AJAX中的UpdatePanel功能大大增強,同時其更新策略也更加複雜,列舉如下(順序同樣重要!且首先請確保理解了上面一節中非同步回送和整頁回送的區別):
- 整頁回送將更新頁面中所有的UpdatePanel。
- 在伺服器端調用某個UpdatePanel的Update()方法將更新該UpdatePanel。
- 若某個UpdatePanel的UpdateMode屬性為Always,則任意的一次非同步回送均將更新該UpdatePanel。
- 若某個UpdatePanel的UpdateMode屬性為Conditional,則該UpdatePanel的AsyncPostBackTrigger所引發的非同步回送將更新該UpdatePanel。
- 若某個UpdatePanel的UpdateMode屬性為Conditional,且ChildrenAsTriggers屬性為true時,該UpdatePanel包圍的控制項所引發的非同步回送將更新該UpdatePanel。
提示
ASP.NET AJAX中的UpdatePanel的實現方式從本質上來說和Atlas中的UpdatePanel沒什麼區別,所以應用於Atlas中UpdatePanel的部分提示將仍舊適用,請參考:
- Atlas UpdatePanel簡要介紹
- Atlas UpdatePanel提示以及常見問題
後記
相對於ScriptManager,UpdatePanel的變化顯得“仁慈”了許多,加上完善的官方文檔協助,今晚我基本上熟悉了新的UpdatePanel的使用方法。但時間同樣倉促,行文依然草率,依舊沒有過多潤色,也沒有任何的一步步的樣本程式……自然也會有很多地方顯得比較難懂——不過本文並不是基礎的入門文章,作為從Atlas轉向ASP.NET AJAX的讀者,您應該能夠理解文中的含義並很快對新的UpdatePanel熟悉起來。
其中錯誤之處,請各位不吝批評指教,或者討論分享心得!再次感謝大家對我的支援!