AJAX.NET 文檔(英文)和網站(英文)對開發人員快速入門非常有用。在介紹使用此技術的一些具體樣本之前,我們將簡要回顧您所需要知道的核心步驟。
首先從 AJAX.NET 專案網站(英文)上下載並解壓縮 AJAX 檔案,然後按照您的喜好在 Visual Basic .NET 或 C# 中建立新的 ASP.NET 項目,再向 AJAX.DLL 檔案添加引用(英文)。唯一的額外配置步驟是在 <system.web> 元素中(位於 web.config 檔案中)添加以下代碼。
<configuration>
<system.web>
<httpHandlers>
<!-- Register the ajax handler -->
<add verb="POST,GET" path="ajax/*.ashx" type="Ajax.PageHandlerFactory, Ajax" />
</httpHandlers>
</system.web>
</configuration>
為了使伺服器端函數在 JavaScript 中可用,必須做兩件事情。首先,要使用的函數必須標有 Ajax.AjaxMethodAttribute。其次,在頁載入事件期間,必須通過調用 Ajax.Utility.RegisterTypeForAjax 來註冊包含這些函數的類。聽起來似乎有些複雜,但請不必擔心;實際上只需要在代碼中多加兩行。讓我們看一個樣本。
//C# public class Sample :System.Web.UI.Page { private void Page_Load(object sender, System.EventArgs e)
{ //註冊我們感興趣的包含伺服器端函數
//的類
Ajax.Utility.RegisterTypeForAjax(typeof(Sample));
}
[Ajax.AjaxMethod()]
public string GetMessageOfTheDay()
{ return "Experience is the mother of wisdom"; }
}
'VB.NET Public Class Sample Inherits System.Web.UI.Page
Private Sub Page_Load(sender AsObject, e As EventArgs)
Handles MyBase.Load
'註冊我們感興趣的包含伺服器端函數
'的類 Ajax.Utility.RegisterTypeForAjax(GetType(Sample))
End Sub
<Ajax.AjaxMethod()> _
Public Function GetMessageOfTheDay() As String
Return "Experience is the mother of wisdom"
End Function
End Class
以上樣本首先告知 Ajax.NET 在 Sample 類中尋找友好的 Ajax 方法。它正好是與實際頁相同的類,但是它可以是任意 .NET 類,或可以註冊多個類。然後,Ajax.NET 將瀏覽指定的類,來尋找標有 AjaxMethodAttribute 的所有方法,其中 Sample 類有一個 GetMessageOfTheDay。
完成後,剩下唯一要做的就是在 JavaScript 中使用它。Ajax.NET 自動建立與註冊的類具有相同名稱的 JavaScript 變數(在本例中將為 Sample),它提供與 AjaxMethod 具有相同名稱的函數(在本例中為 GetMessageOfTheDay)。如下所示。
<script language="javascript">
Sample.GetMessageOfTheDay(GetMessageOfTheDay_CallBack);
function GetMessageOfTheDay_CallBack(response)
{ alert(response.value); }
</script>
除了 JavaScript 回呼函數以外,JavaScript GetMessageOfTheDay 還需要與其伺服器端對應部分相同的參數(在此情況下,沒有參數),以便在完成時執行並傳遞響應。在此,我們看到 AJAX 在工作時的非同步特性,因為對 GetMessageOfTheDay 的調用不阻礙執行其他 JavaScript 代碼,也不阻礙使用者繼續在頁上進行操作。完成伺服器端處理時,Ajax.NET 調用指定的回呼函數 GetMessageOfTheDay_CallBack,並向其傳遞由伺服器端傳回值組成的響應。
伺服器端代碼和 JavaScript 代碼之間的映射可能有些混亂。圖 1 簡要顯示了伺服器端代碼和 JavaScript 代碼,以及兩者之間的映射。
圖 1:伺服器端代碼和 JavaScript 代碼之間的映射
當然令人感興趣的 Ajax.NET 還有更多內容值得介紹,例如對 .NET 類型的支援和豐富的回調響應(它不僅僅是值)。以下樣本將會重點介紹某些功能,希望協助您理解 AJAX 如何協助您建立成功的應用程式。
樣本 1:連結的下拉式清單
本文的開始簡要地討論了用於連結兩個 DropDownList 的兩種傳統方法。當選定的索引更改時,返回頁;或者將所有可能的資料載入到 JavaScript 數組並動態顯示。希望您可以看到 AJAX 如何替代這兩種解決方案。
首先,讓我們來看一下我們的資料介面,並從該資料介面驅動樣本。我們的資料訪問層將提供兩種方法:第一種方法將檢索系統支援的省/地區的列表,第二種方法將擷取省/地區 ID 並返回州/省的列表。由於這是純資料訪問,因此我們只需要使用方法。
//C# public static DataTable GetShippingCountries();
public static DataView GetCountryStates(int countryId);
'VB.NET Public Shared Function GetShippingCountries() As DataTable
Public Shared Function GetCountryStates(ByVal countryId As Integer) As DataView
現在,讓我們轉到相反面,建立簡單的 Web Form。
<asp:DropDownList ID="countries" Runat="server" />
<asp:DropDownList ID="states" Runat="server" />
<asp:Button ID="submit" Runat="server" Text="Submit" />
Page_Load 事件同樣簡單,和前述的 Web Form一樣。我們使用資料訪問層來檢索可用的省/地區,並將其綁定到 countriesDropDownList 中。
//C# if (!Page.IsPostBack)
{
countries.DataSource = DAL.GetShippingCountries();
countries.DataTextField = "Country";
countries.DataValueField = "Id";
countries.DataBind();
countries.Items.Insert(0, new ListItem("Please Select", "0"));
}
通常,代碼到此為止。首先,我們將建立要從 JavaScript 調用的伺服器端函數。
'VB.NET <Ajax.AjaxMethod()> _
Public Function GetStates (ByVal countryId As Integer) As DataView
Return DAL.GetCountryStates(countryId)
End Function
這與您通常使用的任何其他函數一樣:它需要我們想要獲得的省/地區的 ID,並將該請求傳遞給 DAL。唯一的不同是我們已使用 AjaxMethodAttribute 標記了該方法。最後剩餘的伺服器端步驟是通過調用 RegisterTypeForAjax 使用 Ajax.NET 來註冊包含上述方法的類(在此情況下,是我們的下面的代碼)。
//C# Ajax.Utility.RegisterTypeForAjax(typeof(Sample));
'VB.NET Ajax.Utility.RegisterTypeForAjax(GetType(Sample))
我們已基本完成;剩餘的就是從 JavaScript 調用 GetStates 方法和處理響應。當使用者從省/地區列表中選擇新項時,我們想在邏輯上調用 GetStates。為此,我們將觸發 JavaScript onChange 事件。這樣就稍微更改了我們的 Web Form代碼。
<asp:DropDownList onChange="LoadStates(this)" ID="countries" Runat="server" />
JavaScript LoadStates 函數將負責通過由 Ajax.NET 建立的代理髮出非同步請求。請記住,預設情況下,Ajax.NET 建立的代理的格式為 <RegisteredTypeName>.<ServerSideMethodName>。在我們的樣本中,將為 Sample.GetStates。我們還想傳入省/地區 ID 參數和完成伺服器端函數後 Ajax.NET 應調用的回呼函數。
//JavaScript function LoadStates(countries)
{
var countryId = countries.options[countries.selectedIndex].value;
Sample.GetStates(countryId, LoadStates_CallBack);
}
最後一個步驟是處理我們的 LoadStates_CallBack 函數中的響應。Ajax.NET 最有用的功能大概是它支援很多 .NET 類型(我已經多次提到這一點)。回顧一下返回 DataView 的服務端函數。JavaScript 知道 DataView 什嗎?什麼也不知道,但是 JavaScript 是物件導向的語言,而且 Ajax.NET 不只能夠建立與 .NET DataView 相似的對象,還能將該函數返回的值對應到 JavaScript 副本。您應該記住 JavaScript DataView 只不過是實際 DataView 的副本,目前除了能夠遍曆行和訪問列值以外不支援其他更多功能(例如設定 RowFilter 或 Sort 屬性的功能)。
function LoadStates_CallBack(response)
{ //如果伺服器端代碼出現異常
if (response.error != null)
{ //我們應該能做得更好 alert(response.error); return; }
var states = response.value;
//如果不是我們所希望的響應
if (states == null || typeof(states) != "object")
{ return; }
//獲得州下拉式清單 var statesList = document.getElementById("states");
statesList.options.length = 0;
//重設州下拉式清單
//記住,其長度不是 JavaScript 中的 Length
for (var i = 0; i < states.length; ++i)
{ //如命名屬性一樣公開行的列
statesList.options[statesList.options.length] = new Option(states[i].State, states[i].Id);
}
}
經過一些錯誤檢查之後,前面的 JavaScript 獲得州下拉式清單,遍曆響應的值,並動態地將選項添加到該下拉式清單中。代碼清晰、簡單並與 C# 和 Visual Basic .NET 非常相似。就我個人而言(作為基於伺服器端變數建立了 JavaScript 數組並將它們連結在一起的開發人員),我還要一段時間才能相信它真的起作用了。
有一個可能不太明顯的主要問題。由於 DropDownList 是在 JavaScript 中動態建立的,因此它的項不屬於 ViewState,並且不被維護。這意味著按鈕的 OnClick 事件處理常式需要進行一些額外的修改。
'VB.NET
Private Sub submit_Click(sender As Object, e As EventArgs)
Dim selectedStateId As String = Request.Form(states.UniqueID)
'應進行一些使用者驗證...
states.DataSource = DAL.GetCountryStates(Convert.ToInt32(countries.SelectedIndex))
states.DataTextField = "State"
states.DataValueField = "Id" states.DataBind()
states.SelectedIndex = states.Items.IndexOf(states.Items.FindByValue(selectedStateId))
End Sub
首先,我們不能使用 states.SelectedValue 屬性,而必須使用 Request.Form。其次,如果我們想向使用者重新顯示該列表,需要重新使用相同的資料存取方法綁定州 DropDownList。最後,必須以編程方式設定選定的值。