本文主要列举了省市三级联动的DropDownList+Ajax的三种框架(aspnet/Jquery/ExtJs)示例。前段时间需要作一个的Web前端应用,需要用多个框架,一个典型的应用场景是省市三级联动,基于此应用,特将三种主要的ajax框架略作整理,方便有需要的朋友查阅。
在示例之前,我们先设置一个演示数据源,新建一个项目,项目结构如图:

主要文件如下:
AreaModel.cs:
03 |
using System.Collections.Generic; |
04 |
namespace Downmoon.Framework.Model |
09 |
private string m_Area_ID; |
15 |
get { return m_Area_ID; } |
16 |
set { m_Area_ID = value; } |
18 |
private string m_Area_Name; |
22 |
public string Area_Name |
24 |
get { return m_Area_Name; } |
25 |
set { m_Area_Name = value; } |
27 |
private double m_Area_Order; |
31 |
public double Area_Order |
33 |
get { return m_Area_Order; } |
34 |
set { m_Area_Order = value; } |
36 |
private int m_Area_Layer; |
42 |
get { return m_Area_Layer; } |
43 |
set { m_Area_Layer = value; } |
45 |
private string m_Area_FatherID; |
49 |
public string Area_FatherID |
51 |
get { return m_Area_FatherID; } |
52 |
set { m_Area_FatherID = value; } |
55 |
public Area(string id, string name, double order, int layer, string father) |
58 |
this.Area_Name = name; |
59 |
this.m_Area_Order = order; |
60 |
this.m_Area_Layer = layer; |
61 |
this.m_Area_FatherID = father; |
AreaControl.cs:
03 |
using System.Collections.Generic; |
04 |
using Downmoon.Framework.Model; |
05 |
namespace Downmoon.Framework.Controllers |
07 |
public class AreaList : IArea |
10 |
private static AreaList instance; |
11 |
public static AreaList Instance |
15 |
if (AreaList.instance == null) |
17 |
AreaList.instance = new AreaList(); |
19 |
return AreaList.instance; |
22 |
public List<Area> GetAreaList() |
24 |
List<Area> Areas = new List<Area>(); |
25 |
Areas.Add(new Area("110000", "北京市", 0, 1, "000000")); |
26 |
Areas.Add(new Area("110100", "市辖区", 0, 2, "110000")); |
27 |
Areas.Add(new Area("110101", "东城区", 0, 3, "110100")); |
28 |
Areas.Add(new Area("110102", "西城区", 0, 3, "110100")); |
29 |
Areas.Add(new Area("110103", "崇文区", 0, 3, "110100")); |
30 |
Areas.Add(new Area("330000", "浙江省", 0, 1, "000000")); |
31 |
Areas.Add(new Area("330100", "杭州市", 0, 2, "330000")); |
32 |
Areas.Add(new Area("330200", "宁波市", 0, 2, "330000")); |
33 |
Areas.Add(new Area("330102", "上城区", 0, 3, "330100")); |
34 |
Areas.Add(new Area("330103", "下城区", 0, 3, "330100")); |
35 |
Areas.Add(new Area("330104", "江干区", 0, 3, "330100")); |
36 |
Areas.Add(new Area("330105", "拱墅区", 0, 3, "330100")); |
37 |
Areas.Add(new Area("330106", "西湖区", 0, 3, "330100")); |
38 |
Areas.Add(new Area("330203", "海曙区", 0, 3, "330200")); |
39 |
Areas.Add(new Area("330204", "江东区", 0, 3, "330200")); |
40 |
Areas.Add(new Area("330205", "江北区", 0, 3, "330200")); |
41 |
Areas.Add(new Area("330206", "北仑区", 0, 3, "330200")); |
42 |
Areas.Add(new Area("330211", "镇海区", 0, 3, "330200")); |
45 |
public List<Area> GetAreaListFindByParentID(string filter) |
47 |
return GetAreaList().FindAll( |
50 |
return ar.Area_FatherID == filter; |
Factory.cs
03 |
using System.Collections.Generic; |
05 |
namespace Downmoon.Framework.Controllers |
09 |
public static IArea GetAreaController() |
11 |
return AreaList.Instance; |
IArea.cs
03 |
using System.Collections.Generic; |
05 |
using Downmoon.Framework.Model; |
06 |
namespace Downmoon.Framework.Controllers |
08 |
public interface IArea |
10 |
List<Area> GetAreaList(); |
11 |
List<Area> GetAreaListFindByParentID(string filterID); |
一、基于aspnet自带的Ajax框架,主要好处是与asp.net完全集成,无需写过多的 js。缺点是在framework2下需作一些设置,在Framework 4下无需设置。
Framework 2:
需首先在web.config文件中作配置:
05 |
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> |
06 |
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> |
07 |
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/> |
08 |
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> |
09 |
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere" /> |
10 |
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" /> |
11 |
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" /> |
17 |
<customErrors defaultRedirect="" /> |
18 |
<trace mostRecent="true" pageOutput="true" /> |
21 |
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> |
26 |
<add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> |
30 |
<remove verb="*" path="*.asmx"/> |
31 |
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> |
32 |
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> |
33 |
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/> |
36 |
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> |
41 |
<validation validateIntegratedModeConfiguration="false"/> |
43 |
<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> |
46 |
<remove name="WebServiceHandlerFactory-Integrated" /> |
47 |
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" |
48 |
type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> |
49 |
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" |
50 |
type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> |
51 |
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> |
前台页面:
02 |
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"> |
05 |
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> |
07 |
<table width="500" border="0" cellpadding="0" cellspacing="2" > |
09 |
<td height="25" bgcolor="#EAEAEA" > |
12 |
<td bgcolor="#f7f7f7"> |
13 |
<asp:DropDownList ID="dpProvince" runat="server" |
14 |
AutoPostBack="true" onselectedindexchanged="dpProvince_SelectedIndexChanged" /> |
15 |
<asp:DropDownList ID="dpCity" runat="server" AutoPostBack="true" |
16 |
onselectedindexchanged="dpCity_SelectedIndexChanged" /> |
17 |
<asp:DropDownList ID="dpArea" runat="server" AutoPostBack="false" |
22 |
<td height="25" bgcolor="#EAEAEA" > |
24 |
<td bgcolor="#f7f7f7"> |
25 |
<asp:UpdateProgress ID="UpdateProgress1" runat="server"> |
27 |
正在查询,请稍候……………………</ProgressTemplate> |
35 |
<asp:AsyncPostBackTrigger ControlID="dpProvince" EventName="SelectedIndexChanged" /> |
36 |
<asp:AsyncPostBackTrigger ControlID="dpCity" EventName="SelectedIndexChanged" /> |
Framework 4:与代码完全一样,只是无需在web.config中作配置。
如图:

二、基于JQuery1.4.1的Ajax框架,主要好处是与后续版本的asp.net完全集成。
基于ashx作一个 Request,主要代码:
03 |
using System.Collections.Generic; |
05 |
using Downmoon.Framework.Controllers; |
06 |
using Downmoon.Framework.Model; |
08 |
namespace dropdown_JQuery14_Net2 |
11 |
/// Summary description for AjaxRequest |
13 |
public class AjaxRequest : IHttpHandler |
15 |
public void ProcessRequest(HttpContext context) |
17 |
string Area_FatherID = string.Empty; |
18 |
if (context.Request["pid"] != null) |
19 |
{ Area_FatherID = context.Request["pid"].ToString(); } |
20 |
string parentId = string.Empty; |
24 |
List<Area> list = Factory.GetAreaController().GetAreaListFindByParentID(Area_FatherID); |
25 |
context.Response.ContentType = "application/json"; |
26 |
context.Response.ContentEncoding = Encoding.UTF8; |
27 |
context.Response.Write(ListToJson(list)); |
28 |
context.Response.End(); |
30 |
public string ListToJson(List<Area> list) |
32 |
StringBuilder sb = new StringBuilder(); |
36 |
for (int i = 0; i < list.Count; i++) |
39 |
sb.Append("\"Area_ID\":\"" + list[i].Area_ID + "\","); |
40 |
sb.Append("\"Area_Name\":\"" + list[i].Area_Name + "\""); |
42 |
if (i != list.Count - 1) |
52 |
public bool IsReusable |
前台:aspx
004 |
<head runat="server"> |
006 |
<mce:style type="text/css"><!-- |
018 |
--></mce:style><style type="text/css" mce_bogus="1"> #dpCity |
029 |
<mce:script language="javascript" type="text/javascript" src="Scripts/jquery-1.4.1.js" mce_src="Scripts/jquery-1.4.1.js"></mce:script> |
032 |
<form id="form1" runat="server"> |
034 |
请选择省/市/区: <asp:DropDownList ID="dpProvince" runat="server" /> |
035 |
<asp:DropDownList ID="dpCity" runat="server"> |
037 |
<asp:DropDownList ID="dpArea" runat="server" AutoPostBack="false" /> |
039 |
<mce:script language="javascript" type="text/javascript"><!-- |
042 |
var $dp1 = $("#dpProvince"); |
043 |
var $dp2 = $("#dpCity"); |
044 |
var $dp3 = $("select[name$=dpArea]"); |
047 |
loadAreas("000000", "0"); |
048 |
$dp1.bind("change keyup", function () { |
049 |
if ($(this).val() != "") { |
052 |
var strPid = $dp1.attr("value"); |
053 |
loadAreas(strPid, "1"); |
056 |
$dp2.fadeOut("slow"); |
059 |
$dp2.bind("change keyup", function () { |
060 |
var strCId = $dp2.attr("value"); |
061 |
if ($(this).val() != "") { |
062 |
loadAreas(strCId, "2"); |
065 |
$dp3.fadeOut("slow"); |
069 |
function loadAreas(selectedItem, level) { |
070 |
$.getJSON("AjaxRequest.ashx?pid=" + selectedItem, function (data) { |
073 |
$("#dpProvince").html(""); |
074 |
$("#dpProvince").append("<option value='' selected='selected'>请选择...</option>"); |
075 |
for (var i = 0; i < data.length; i++) { |
076 |
$("#dpProvince").append($("<option></option>").val(data[i].Area_ID).html(data[i].Area_Name)); |
080 |
$("#dpCity").html(""); |
081 |
$("#dpCity").append("<option value='' selected='selected'>请选择...</option>"); |
082 |
for (var i = 0; i < data.length; i++) { |
083 |
$("#dpCity").append($("<option></option>").val(data[i].Area_ID).html(data[i].Area_Name)); |
087 |
$("#dpArea").html(""); |
088 |
$("#dpArea").append("<option value='' selected='selected'>请选择...</option>"); |
089 |
for (var i = 0; i < data.length; i++) { |
090 |
$("#dpArea").append($("<option></option>").val(data[i].Area_ID).html(data[i].Area_Name)); |


三、基于ExtJS 3.2的Ajax框架。
后台ashx:
03 |
using System.Collections.Generic; |
05 |
using Downmoon.Framework.Controllers; |
06 |
using Downmoon.Framework.Model; |
08 |
namespace dropdown_ExtJS32_Net2.Ajax |
11 |
/// Summary description for GetAreaXml |
13 |
public class GetAreaXml : IHttpHandler |
16 |
public void ProcessRequest(HttpContext context) |
18 |
string parentId = "000000"; |
19 |
if (context.Request["pid"] != null) |
21 |
parentId = context.Request["pid"].ToString(); |
24 |
////string parentId2 = "000000"; |
25 |
////if (context.Request["pid2"] != null) |
27 |
//// parentId2 = context.Request["pid2"].ToString(); |
29 |
#region tony 2010.2.7 update |
30 |
List<Area> list = new List<Area>(); |
33 |
list = Factory.GetAreaController().GetAreaListFindByParentID(parentId); |
35 |
////else if (parentId2.Length > 0) |
37 |
//// list = Factory.GetAreaController().GetAreaListFindByParentID(parentId2); |
40 |
context.Response.AddHeader("Cache-Control", "no-cache, must-revalidate"); |
41 |
context.Response.ContentEncoding = System.Text.Encoding.UTF8; |
42 |
context.Response.ContentType = "text/html"; |
43 |
StringBuilder sb = new StringBuilder(); |
45 |
for (int i = 0; i < list.Count; i++) |
47 |
sb.Append("{\"Area_Name\":\"" + list[i].Area_Name + "\","); |
48 |
sb.Append("\"Area_ID\":\"" + list[i].Area_ID + "\"},"); |
50 |
string json = sb.ToString().TrimEnd(','); |
51 |
context.Response.Write("{\"Results\":[" + json + "]}"); |
54 |
public bool IsReusable |
前台页面.aspx
05 |
<title>demo a dropdownlist by extjs 3.2 </title> |
06 |
<link rel="stylesheet" href="Scripts/ext/3.2/resources/css/ext-all.css" mce_href="Scripts/ext/3.2/resources/css/ext-all.css" /> |
07 |
<mce:script type="text/javascript" src="Scripts/ext/3.2/adapter/ext/ext-base.js" mce_src="Scripts/ext/3.2/adapter/ext/ext-base.js"></mce:script> |
08 |
<mce:script type="text/javascript" src="Scripts/ext/3.2/ext-all.js" mce_src="Scripts/ext/3.2/ext-all.js"></mce:script> |
09 |
<mce:script type="text/javascript"><!-- |
10 |
Ext.onReady(function () { |
14 |
return Ext.get(arguments[0]); |
19 |
var cityCtrl = $(arguments[1]).child("select"); |
20 |
var cityCtrlContainer = $(arguments[1]); |
21 |
cityCtrl.dom.options.length = 0; |
22 |
if ($(arguments[0]).getValue() == "") { cityCtrlContainer.hide(); return; } |
24 |
cityCtrl.disabled = true; |
25 |
var selectValue2 = $(arguments[0]).getValue(); |
28 |
params: { pid: selectValue2 }, |
30 |
success: function (result, request) { |
32 |
var jsonData = Ext.util.JSON.decode(result.responseText); |
34 |
if (jsonData.Results.length > 0) { |
35 |
cityCtrl.dom.options.add(new Option("请选择", "000000")); |
36 |
for (var i = 0; i < jsonData.Results.length; i++) { |
37 |
cityCtrl.dom.options.add(new Option(jsonData.Results[i].Area_Name, jsonData.Results[i].Area_ID)); |
39 |
cityCtrl.disabled = false; |
40 |
cityCtrlContainer.show(); |
43 |
cityCtrlContainer.hide(); |
46 |
failure: function (result, request) { Ext.MessageBox.alert('Failed', 'Successfully posted form: ' + action.date); } |
54 |
<form id="form1" runat="server"> |
55 |
<table width="500" border="0" cellpadding="0" cellspacing="2"> |
57 |
<td height="25" bgcolor="#EAEAEA"> |
58 |
<div style="float: left; height: 20px; line-height: 20px;"> |
60 |
<asp:DropDownList Style="float: left;" mce_Style="float: left;" ID="dropProvince" runat="server" /> |
61 |
<div style="float: left; height: 20px; line-height: 20px;"> |
63 |
<asp:Panel ID="panelArea" runat="server"> |
64 |
<asp:DropDownList Style="float: left;" mce_Style="float: left;" ID="dropArea" runat="server" /> |
65 |
<div style="float: left; height: 20px; line-height: 20px;"> |
68 |
<asp:Panel ID="panelArea2" runat="server" > |
69 |
<asp:DropDownList Style="float: left;" mce_Style="float: left;" ID="dropArea2" runat="server" /> |
70 |
<div style="float: left; height: 20px; line-height: 20px;"> |
效果如图:
