一、引言
微軟的ASP.NET AJAX架構,作為一個相對比較完善的AJAX架構,有許多方面值得我們作深入研究。本文中,我們将結合一個具體的例子試圖探究ASP.NET AJAX架構的用戶端生命周期過程。
二、ASP.NET AJAX用戶端生命周期原理
因為ASP.NET AJAX架構在開發思路上極大地借鑒了ASP.NET 2.0的開發技術,而且将會被逐漸“收錄”到ASP.NET 2.0中;是以,一個ASP.NET AJAX頁面也存在自己的生命周期,而且與一個ASP.NET 2.0 Web頁面生命周期之間存在很大的可比之處。
ASP.NET AJAX頁面中的用戶端事件能夠支援我們無論是針對傳統回送還是對于異步回送(即“局部頁面重新整理”)都能定制自己的使用者界面。而且,這些事件在其整個浏覽器端頁面生命周期中還可以幫助我們管理和使用自定義的腳本。
這些用戶端事件均集中在ASP.NET AJAX架構用戶端類庫中。當加載一個帶有ASP.NET AJAX伺服器控件的頁面時,這些類都會由架構自動地執行個體化。借助于這些類用戶端提供的一些API,我們能夠輕松地實作頁面中用戶端事件的綁定功能。因為這部分ASP.NET AJAX用戶端庫完全獨立于浏覽器,是以我們編寫出的代碼當然可以工作在目前所有流行的浏覽器環境中。
在衆多的用戶端事件中,最關鍵的一個事件當屬初始化請求(‘GET ’方式)和異步回送期間Application執行個體的load事件。
【注意】當load事件處理器程式中的腳本開始運作時,所有其它的腳本群組件都應該已經被加載并且完全可用了。
當使用伺服器控件UpdatePanel進行局部頁面重新整理時,所有相關用戶端事件中最重要的就是Sys.WebForms.PageRequestManager類中相關的幾個事件。這幾個重要用戶端事件幫助你完全一些正常任務,例如撤銷回送,為某個回送設定更高的優先級,還可以使UpdatePanel控件在重新整理期間産生一定的動畫效果,等等。深入了解所有這些用戶端事件對于我們建立頁面或開發基于ASP.NET AJAX架構的元件都将有很大的幫助。例如,如果你是一位網頁開發人員,你可以為頁面在加載和解除安裝期間使用自己的定制腳本。
三、用戶端類解析
前面我們簡單提到過,Sys.Application類和Sys.WebForms.PageRequestManager類是在整個ASP.NET AJAX Web頁面用戶端生命周期期間兩個最主要的類。下面,我們将進行逐一分析。
當浏覽器請求一個包含有ScriptManager控件的頁面時,Application類就被執行個體化。Application類與伺服器端的Page控件極其類似(Page控件繼承自伺服器端的Control類),不過針對引發服務端事件還提供了額外的功能。類似地,Application類派生自用戶端的Sys.Component類;但是它引發的是一系列的用戶端生命周期事件。
如果一個頁面中包含一個ScriptManager控件及數個UpdatePanel控件,那麼這個頁面就可以實作部分更新效果(當然,如果浏覽器支援并啟動局部更新功能的話)。在這種情況下,一個PageRequestManager類的執行個體将在浏覽器端建立并起作用。事實上,這個PageRequestManager執行個體引發的用戶端事件都是關于異步回送方面的。
四、為用戶端事件添加事件處理器
要針對Application類和PageRequestManager類的執行個體所引發的事件添加或移除相應的事件處理器,我們可以使用add_eventname和reomve_eventname方法來完全這些任務。下面這個例子展示了如何為Application對象的init事件添加一個名為MyLoad的事件處理器函數:
Sys.Application.add_init(MyInit);// 添加事件處理器
function MyInit(sender) {…………}
//…………
Sys.Appplication.remove_init(MyInit);//移除相應的事件處理器
這段代碼僅說明了操作的基本文法形式,後面我們将進行具體的舉例說明。
五、處理Application的Load和Unload事件
注意,要處理Application對象的load和unload事件,不需要我們顯式地綁定到把一個事件處理器函數綁定到這些事件上,而是直接使用保留關鍵字pageLoad和pageUnload建立相應的函數即可。下面這個例子展示了如何為Application的load事件添加一個事件處理器函數。
function pageLoad(sender, args) {…………}
【作者注】線上參考資料上也這樣說—“隻須使用保留關鍵字pageLoad和pageUnload建立相應的函數即可”,但要刨根問底起來:這一細節到底是在什麼地方實作?有興趣的讀者可以進一步鑽研随同架構下載下傳的一組“API”;這其實是一些看上去竟然有些“混亂”(估計是經過簡單的“混淆”處理)的函數。
六、其它用戶端有關的事件
在本文中,我們僅專注于探讨由Application和PageRequestManager類提供的事件(因為與這兩個類相關聯的事件在兩個用戶端頁面生命周期中起着至關重要的作用)。其實,微軟的AJAX類庫還包括了一個針對DOM元素事件操作的專用類—Sys.UI.DomEvent。而以下是一些典型的用于添加、清除和移除相應事件處理器函數的全局方法。這些方法包括:
—Sys.UI.DomEvent.addHandler,簡寫為$addHandler;
—Sys.UI.DomEvent.clearHandlers,簡寫為$clearHandlers;
—Sys.UI.DomEvent.removeHandler,簡寫為$removeHandler。
但是,有關DOM元素提供的事件不是本文讨論之列(而且也比較簡單)。
七、Application和PageRequestManager相關事件深度解析
為了友善起見,我們以表格形式舉例出了Application和PageRequestManager類相關的用戶端事件(所有這些事件都是我們可以在支援AJAX ASP.NET技術的頁面中加以操縱的)。至于事件引發的先後順序将在後面的示例中分析。
<b>事件</b>
<b>解釋</b>
Init(初始化事件)
在加載完所有腳本但建立任何一個對象之前引發該事件。如果你在開發一個用戶端元件,那麼,這個init事件為你提供了一個在頁面生命周期内把該元件添加到頁面的時機。此後,該元件即可被在頁面生命周期内的其它元件及腳本所調用。如果你是網頁開發人員,那麼在大多數的情況之下,建議你使用load事件來替代init事件進行有關處理。
【注】init事件隻在頁面開始生成時建立一次。後來的部分頁面重新整理将不會再引發此事件。
Load(加載事件)
該事件在加載完所有腳本并且在該程式中的對象(使用$create建立)全部初始化結束後引發。該事件針對所有到伺服器的回送(也包括異步的回送)都将被引發。
如果你是網頁開發人員,你可以建立一個名為pageLoad的函數,該函數會自動為load事件提供一個處理器函數。注意,這個pageLoad處理器是在所有load事件中的事件處理器(通過add_load方法添加)調用之後被調用的。
此外,load事件僅需要一個Sys.ApplicationLoadEventArgs對象作為參數。你可以通過該參數來決定頁面經局部更新後是否正是被重新整理,還可以确定在上一個load事件引發後建立了哪些元件。
Unload(解除安裝事件)
在釋放所有對象和浏覽器中的window.unload事件發生之前引發此事件。
如果你是網頁開發人員,你可以建立個名為pageUnload的函數;之後,系統會自動為unload事件提供一個事件處理器函數。這個事件恰好是在浏覽器解除安裝頁面之前被調用。因為是最後一次機會,是以在該事件發生期間,我們應當釋放由代碼占用的全部資源。
propertyChanged(屬性改變事件)
當某元件的屬性發生改變時引發該事件。Application對象是從Component類中繼承這個事件的。典型情況下,該事件僅由元件開發人員使用;他在設定某個屬性相應的set通路器的過程中時調用Sys.Component.raisePropertyChange方法時才引發。
此事件需要一個使用Sys.applicationLoadEventArgs對象作為參數。
Disposing(釋放事件)
在釋放Application執行個體時引發該事件。該事件是由Application對象從Component類中繼承來的。
initializeRequest(初始化請求事件)
該事件發生在一個異步請求開始之前。你可以通過使用該事件來取消一個傳統的回送而讓一個異步回送獲得優先執行權。
該事件僅使用一個Sys.WebForms.InitializeRequestEventArgs對象作參數。通過這個對象我們可以操作引發回送的元素甚至是Request對象。該事件還暴露了一個cancel屬性。如果你設定cancel的值為true,那麼,一個新的回送将被撤銷。
beginRequest(開始請求事件)
該事件發生在一個異步請求開始但向伺服器實作回送之前。該事件是在一個回送到伺服器的異步回送開始前引發。如果目前已經存在了一個回送程序,則會被強硬地停止(通過abortPostBack方法)。你可以使用該事件來設定請求的頭部資訊或在頁面中顯示一個動畫以提示該請求正在進行中。
該事件需要一個Sys.WebForms.BeginRequestEventArgs對象作為參數。我們也可以通過這個對象來操作引發回送的元素甚至是Request對象。
pageLoading(頁面正在加載事件)
在接收一個來自伺服器端的異步回送響應之後,且在頁面中任何内容被更新之前引發此事件。在實際開發中,我們可以使用該事件來為需要更新的内容提供某種定制的過渡效果。
該事件需要一個Sys.WebForms.PageLoadingEventArgs對象作為參數。通過該對象,我們可以從最近的異步回送傳回的結果中了解到頁面中的哪些面闆元素(例如div,span等)将被删除和更新。
pageLoaded(頁面加載完成事件)
在所有頁面内容重新整理之後(無論是經同步回送還是異步回送的結果)引發此事件。在同步回送時,隻能建立面闆元素;但在異步回送時,可以建立和更新面闆元素。我們可以使用該事件來管理針對需要更新的内容的某種定制過渡效果。
該事件需要一個Sys.WebForms.PageLoadedEventArgs對象作為參數。該對象提供了關于最近回送時哪些面闆元素被更新和建立的有用資訊。
endRequest(結束請求事件)
在響應完一次異步回送并且頁面得到更新後,或在請求過程中發生了錯誤時引發此事件。如果發生了某個錯誤,頁面将不會被更新。是以,我們可以通過這個事件來提供某種定制的錯誤提示資訊給通路者或把此資訊記錄到錯誤日志中。
該事件需要一個Sys.WebForms.EndRequestEventArgs對象作為eventargs參數。該對象提供了有關被引發的錯誤和錯誤是否被處理的一些有用的資訊;而且我們可以通過此對象操作Response對象。
八、小結
在本篇中,我們将對ASP.NET AJAX用戶端生命周期中的重要事件作詳盡列舉,并給出典型的适用場合。在接下來的下篇中,我們分析一個實際的簡單案例,并試圖對ASP.NET AJAX用戶端生命周期中主要關聯事件的發生順序作深度解析。
本文轉自朱先忠老師51CTO部落格,原文連結:http://blog.51cto.com/zhuxianzhong/59347 ,如需轉載請自行聯系原作者