一、引言
微軟的asp.net ajax框架,作為一個相對比較完善的ajax框架,有許多方面值得我們作深入研究。本文中,我們將結合一個具體的例子試圖探究asp.net ajax框架的客戶端生命周期過程。
【注】閱讀本文最好要結合“asp.net應用程序生命周期概述”和“asp.net頁面生命周期概述”兩篇文章共同學習。
二、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技術的頁面中加以操縱的)。至于事件引發的先后順序將在后面的示例中分析。
事件 | 解釋 |
init(初始化事件) | 在加載完所有腳本但創建任何一個對象之前引發該事件。如果你在開發一個客戶端組件,那么,這個init事件為你提供了一個在頁面生命周期內把該組件添加到頁面的時機。此后,該組件即可被在頁面生命周期內的其它組件及腳本所調用。如果你是網頁開發人員,那么在大多數的情況之下,建議你使用load事件來替代init事件進行有關處理?!咀ⅰ縤nit事件只在頁面開始生成時創建一次。后來的部分頁面刷新將不會再引發此事件。 |
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客戶端生命周期中主要關聯事件的發生順序作深度解析。
新聞熱點
疑難解答
圖片精選