AJAX 入门(第二部分)- 使用 XMLHttpRequest 和 jQuery AJAX 实现级联下拉列表






4.67/5 (37投票s)
本文讨论了在 ASP.NET 应用程序中使用 XMLHttpRequest 和 jQuery AJAX。
这个迷你系列共有三篇文章
- AJAX for Beginners (Part 1) - 理解 ASP.NET AJAX 服务器控件
- AJAX 入门(第二部分)- 使用 XMLHttpRequest 和 jQuery AJAX 实现级联下拉列表
- AJAX for Beginners (Part 3) - 在 ASP.NET 网站中从 JavaScript 调用服务器端方法和使用 Web 服务
引言
本文讨论了 ASP.NET 应用程序使用 XMLHttpRequest
对象和 jQuery AJAX 实现异步功能(即 AJAX)的各种方法。
背景
在本系列的第一部分(Part 1)中,我们了解了 ASP.NET 开发人员在 Web 应用程序中实现 AJAX 功能的各种方法。我们还了解了如何使用 ASP.NET AJAX 服务器控件。现在,本文将重点介绍使用 XMLHttpReuqest
对象和 jQuery AJAX 在 Web 应用程序中实现异步行为。
XMLHttpObject
可以在后台促进客户端和服务器之间的数据交换,也就是说,使用 XMLHttpObject
可以实现部分页面更新。
jQuery 是一个 JavaScript 框架,它使开发人员能够轻松完成许多客户端工作。jQuery AJAX 是一组例程,可在后台提供客户端和服务器之间的通信,从而实现部分页面更新。
Using the Code
在本文中,我们将尝试解决许多开发人员经常遇到的一个常见问题。我们将尝试使用 AJAX 实现级联下拉列表。我们将首先使用 XMLHttpObject
实现此功能,然后使用 jQuery AJAX 实现。
在开始处理手头的问题之前,让我们先了解一下解决方案和所需的功能。假设我们有一个数据库,其中包含所有大陆和国家/地区的列表。用户将看到两个下拉列表。第一个下拉列表将包含大陆列表,当用户从该列表中选择任何大陆时,第二个下拉列表应异步更新,即无需导致任何回发。
让我们看一下包含大陆和国家/地区列表的数据库表以及其中包含的数据。
注意:数据库没有经过任何优化或规范化,因为这并非本文的重点。
现在,我们有一个负责所有数据库通信的辅助类。理想情况下,此类应作为数据访问层的独立解决方案存在,但为简化起见,我创建了这个类。
public class DBHelper
{
public static DataTable GetContinentList()
{
DataTable result = null;
try
{
using (SqlConnection con = new SqlConnection(
ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = "select distinct continentName from Countries";
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
result = new DataTable();
da.Fill(result);
}
}
}
}
catch (Exception)
{
//Pokemon exception handling
}
return result;
}
public static DataTable GetCountriesList(string continentNmame)
{
DataTable result = null;
try
{
using (SqlConnection con = new SqlConnection(
ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = "select countryName from Countries
where continentName = @continent";
cmd.Parameters.Add(new SqlParameter("@continent", continentNmame));
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
result = new DataTable();
da.Fill(result);
}
}
}
}
catch (Exception)
{
//Pokemon exception handling
}
return result;
}
}
此类将有助于检索大陆列表以及特定于该大陆的国家/地区列表。现在让我们开始处理实际问题。
使用 XMLHttpObject
让我们创建一个包含两个下拉列表的页面(default.aspx)。我们将第一个下拉列表初始化为第一个大陆名称,将第二个下拉列表初始化为该大陆的国家/地区。然后,我们将使用 XMLHttpObject
根据用户对第一个下拉列表的选择来更改第二个下拉列表的内容。此页面的代码隐藏将仅包含 page_load
的逻辑。
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
//Let us populate the list of continents in the first drop down
drpContinent.DataSource = DBHelper.GetContinentList();
drpContinent.DataTextField = "continentName";
drpContinent.DataValueField = "continentName";
drpContinent.DataBind();
//Set the second dropdown as the list of all countries of selected continent
drpCountry.DataSource = DBHelper.GetCountriesList(drpContinent.SelectedValue);
drpCountry.DataTextField = "countryName";
drpCountry.DataValueField = "countryName";
drpCountry.DataBind();
}
}
现在,我们要做的下一件事是在客户端处理第一个下拉列表的 onchange
事件。
<asp:DropDownList ID="drpContinent" runat="server" onchange="UpdateCountries();">
</asp:DropDownList>
现在,要使用 XMLHttpObject
根据用户选择获取国家/地区列表,我们需要执行以下操作:
- 创建
XmlHttpObject
。 - 检索用户当前对第一个下拉列表的选择。
- 使用
XMLHttpObject
将此值通过查询字符串传递给服务器上的网页。 - 处理我们刚刚进行的异步请求的响应。
- 检索响应中的值。
- 根据响应中找到的新值更改第二个下拉列表项。
上述算法中需要注意的重要一点是,我们需要一个页面来处理此异步请求,提取查询字符串,然后将结果推送到响应中。让我们为此目的创建一个名为 frmForAjaxCalls.aspx 的页面并实现该功能。
public partial class frmForAjaxCalls : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string continentName = Request.QueryString["cont"] as string;
if (continentName != null)
{
DataTable table = DBHelper.GetCountriesList(continentName.Trim());
string result = string.Empty;
foreach (DataRow r in table.Rows)
{
result += r["countryName"].ToString() + ";";
}
Response.Clear();
Response.Write(result);
Response.End();
}
}
}
现在,唯一剩下的就是客户端 JavaScript 代码,它将使用 XMLHttpObject
调用此页面。以下代码将显示如何完成。
var xmlHttp;
function UpdateCountries()
{
//Let us create the XML http object
xmlHttp = null;
if(window.XMLHttpRequest)
{
//for new browsers
xmlHttp = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
//for old ones
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
if(xmlHttp != null)
{
//everything so far is just fine, let's proceed
//Retrieve the value of the first drop down list
var contName = document.getElementById('<%=drpContinent.ClientID %>').value;
//Handle the response of this async request we just made(subscribe to callback)
xmlHttp.onreadystatechange=state_Change;
//Pass the value to a web page on server as query string using XMLHttpObject.
xmlHttp.open("GET","frmForAjaxCalls.aspx?cont="+contName,true);
xmlHttp.send(null);
}
}
//Handle the response of this async request
function state_Change()
{
if (xmlHttp.readyState==4)
{
// 4 = “loaded”
if (xmlHttp.status==200)
{
//request was successful. so Retrieve the values in the response.
var countries = xmlHttp.responseText.split(';');
var length = countries.length;
//Change the second dropdownlists items as per the new values found in response.
//let us remove existing items
document.getElementById('<%=drpCountry.ClientID %>').options.length = 0;
//Now add the new items to the dropdown.
var dropDown = document.getElementById('<%=drpCountry.ClientID %>');
for(var i = 0; i < length - 1; ++i)
{
var option = document.createElement("option");
option.text = countries[i];
option.value = countries[i];
dropDown.options.add(option);
}
}
}
}
现在,当我们运行此页面时,我们可以看到第一个下拉列表中的选择将触发与服务器的异步通信,第二个下拉列表将用该大陆的国家/地区的值填充。所有这些都是在没有任何服务器回发的情况下完成的。
使用 jQuery AJAX
让我们创建一个类似的页面,其中包含两个下拉列表(default2.aspx)。我们将第一个下拉列表初始化为第一个大陆名称,将第二个下拉列表初始化为该大陆的国家/地区。然后,我们将使用 jQuery AJAX 根据用户对第一个下拉列表的选择来更改第二个下拉列表的内容。此页面的代码隐藏将包含 page_load
的逻辑。
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
//Let us populate the list of continents in the first drop down
drpContinent.DataSource = DBHelper.GetContinentList();
drpContinent.DataTextField = "continentName";
drpContinent.DataValueField = "continentName";
drpContinent.DataBind();
//Set the second dropdown as the list of all countries of selected continent
drpCountry.DataSource = DBHelper.GetCountriesList(drpContinent.SelectedValue);
drpCountry.DataTextField = "countryName";
drpCountry.DataValueField = "countryName";
drpCountry.DataBind();
}
}
现在,与 XMLHttpObject
不同,如果我们使用 jQuery
,则无需创建另一个页面来处理异步请求。我们可以在 asme 页面中创建一个 static
函数(或者,如果需要,也可以创建一个单独的页面),该函数将接受一些参数并返回一些值。将参数传递给此函数、调用此函数以及处理结果将是客户端上 jQuery 的职责。让我们看看这个函数。
[System.Web.Services.WebMethod]
public static string OnContinentChange(string continentName)
{
DataTable table = DBHelper.GetCountriesList(continentName.Trim());
string result = string.Empty;
foreach (DataRow r in table.Rows)
{
result += r["countryName"].ToString() + ";";
}
return result;
}
此 static
函数还应使用 WebMethod
属性进行装饰。这表明此方法将从客户端调用。
注意:具有 WebMethod
属性的此 static
方法可以被视为一个小型 Web 服务,可以使用此页面的 URL 从客户端访问。
现在,要使用 jQuery AJAX 根据用户选择获取国家/地区列表,我们需要执行以下操作:
- 处理第一个下拉列表的
onchange
事件。 - 检索用户当前对第一个下拉列表的选择。
- 创建一个
JSON
对象以将此数据传递到服务器。 - 指定要调用的页面/方法名称。
- 处理响应回调。
- 检索响应中的值。
- 根据响应中找到的新值更改第二个下拉列表项。
以下代码将显示如何使用 jQuery 完成此操作。
$(document).ready(function() {
//Handle the change event for the drop down list
$("#drpContinent").change(function() {
//create the ajax request
$.ajax( {
type: "POST", //HTTP method
url: "Default2.aspx/OnContinentChange", //page/method name
data: "{'continentName':'"+$('#drpContinent').val() +"'}", //json to
//represent argument
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) { //handle the callback to handle response
//request was successful. so Retrieve the values in the response.
var countries = msg.split(';');
var length = countries.length;
//Change the second dropdownlists items as per the new values found in response.
//let us remove existing items
document.getElementById('<%=drpCountry.ClientID %>').options.length = 0;
//Now add the new items to the dropdown.
var dropDown = document.getElementById('<%=drpCountry.ClientID %>');
for(var i = 0; i < length - 1; ++i) {
var option = document.createElement("option");
option.text = countries[i];
option.value = countries[i];
dropDown.options.add(option);
}
}
});
});
});
现在,当我们运行此页面时,我们可以看到第一个下拉列表中的选择将触发与服务器的异步通信,第二个下拉列表将用该大陆的国家/地区的值填充。所有这些都是在没有任何服务器回发的情况下完成的。
关注点
我们已经了解了在 ASP.NET 网站中实现 AJAX 行为的两种方法。第一种方法是使用 XMLHttpObject
,第二种方法是使用 jQuery AJAX。我们仅对这两种方法进行了初步了解,以了解如何完成。这两种方法都有许多可自定义的选项,可以实现对异步通信的更好控制。我建议我们详细阅读这两种方法。这将有助于更好地理解事物。
我们还解决了开发人员(尤其是新手)经常遇到的一个常见问题,即创建级联下拉列表。本文介绍了两种实现方法。我们还可以使用 AJAX 控件工具包来实现此功能以及更多 AJAX 功能。但这也许需要另行讨论。
历史
- 2012年6月12日:初版