本文主要列举了省市三级联动的DropDownList+Ajax的三种框架(aspnet/Jquery/ExtJs)示例。前段时间需要作一个的Web前端应用,需要用多个框架,一个典型的应用场景是省市三级联动,基于此应用,特将三种主要的ajax框架略作整理,方便有需要的朋友查阅。
在示例之前,我们先设置一个演示数据源,新建一个项目,项目结构如图:
主要文件如下:
AreaModel.cs:
using
System;
using
System.Collections.Generic;
namespace
Downmoon.Framework.Model
{
#region
PopularArea
public
class
Area
{
private
string
m_Area_ID;
///
<summary>
///
地区编号
///
</summary>
public
string
Area_ID
{
get
{
return
m_Area_ID; }
set
{ m_Area_ID
=
value; }
}
private
string
m_Area_Name;
///
<summary>
///
地区名称
///
</summary>
public
string
Area_Name
{
get
{
return
m_Area_Name; }
set
{ m_Area_Name
=
value; }
}
private
double
m_Area_Order;
///
<summary>
///
排序
///
</summary>
public
double
Area_Order
{
get
{
return
m_Area_Order; }
set
{ m_Area_Order
=
value; }
}
private
int
m_Area_Layer;
///
<summary>
///
层级
///
</summary>
public
int
Area_Layer
{
get
{
return
m_Area_Layer; }
set
{ m_Area_Layer
=
value; }
}
private
string
m_Area_FatherID;
///
<summary>
///
父级ID
///
</summary>
public
string
Area_FatherID
{
get
{
return
m_Area_FatherID; }
set
{ m_Area_FatherID
=
value; }
}
public
Area() { }
public
Area(
string
id,
string
name,
double
order,
int
layer,
string
father)
{
this
.Area_ID
=
id;
this
.Area_Name
=
name;
this
.m_Area_Order
=
order;
this
.m_Area_Layer
=
layer;
this
.m_Area_FatherID
=
father;
}
}
#endregion
}
AreaControl.cs:
using
System;
using
System.Collections.Generic;
using
Downmoon.Framework.Model;
namespace
Downmoon.Framework.Controllers
{
public
class
AreaList : IArea
{
//
Area singleton
private
static
AreaList instance;
public
static
AreaList Instance
{
get
{
if
(AreaList.instance
==
null
)
{
AreaList.instance
=
new
AreaList();
}
return
AreaList.instance;
}
}
public
List
<
Area
>
GetAreaList()
{
List
<
Area
>
Areas
=
new
List
<
Area
>
();
Areas.Add(
new
Area(
"
110000
"
,
"
北京市
"
,
0
,
1
,
"
000000
"
));
Areas.Add(
new
Area(
"
110100
"
,
"
市辖区
"
,
0
,
2
,
"
110000
"
));
Areas.Add(
new
Area(
"
110101
"
,
"
东城区
"
,
0
,
3
,
"
110100
"
));
Areas.Add(
new
Area(
"
110102
"
,
"
西城区
"
,
0
,
3
,
"
110100
"
));
Areas.Add(
new
Area(
"
110103
"
,
"
崇文区
"
,
0
,
3
,
"
110100
"
));
Areas.Add(
new
Area(
"
330000
"
,
"
浙江省
"
,
0
,
1
,
"
000000
"
));
Areas.Add(
new
Area(
"
330100
"
,
"
杭州市
"
,
0
,
2
,
"
330000
"
));
Areas.Add(
new
Area(
"
330200
"
,
"
宁波市
"
,
0
,
2
,
"
330000
"
));
Areas.Add(
new
Area(
"
330102
"
,
"
上城区
"
,
0
,
3
,
"
330100
"
));
Areas.Add(
new
Area(
"
330103
"
,
"
下城区
"
,
0
,
3
,
"
330100
"
));
Areas.Add(
new
Area(
"
330104
"
,
"
江干区
"
,
0
,
3
,
"
330100
"
));
Areas.Add(
new
Area(
"
330105
"
,
"
拱墅区
"
,
0
,
3
,
"
330100
"
));
Areas.Add(
new
Area(
"
330106
"
,
"
西湖区
"
,
0
,
3
,
"
330100
"
));
Areas.Add(
new
Area(
"
330203
"
,
"
海曙区
"
,
0
,
3
,
"
330200
"
));
Areas.Add(
new
Area(
"
330204
"
,
"
江东区
"
,
0
,
3
,
"
330200
"
));
Areas.Add(
new
Area(
"
330205
"
,
"
江北区
"
,
0
,
3
,
"
330200
"
));
Areas.Add(
new
Area(
"
330206
"
,
"
北仑区
"
,
0
,
3
,
"
330200
"
));
Areas.Add(
new
Area(
"
330211
"
,
"
镇海区
"
,
0
,
3
,
"
330200
"
));
return
Areas;
}
public
List
<
Area
>
GetAreaListFindByParentID(
string
filter)
{
return
GetAreaList().FindAll(
delegate
(Area ar)
{
return
ar.Area_FatherID
==
filter;
}
);
}
}
}
Factory.cs
using
System;
using
System.Collections.Generic;
//
using Downmoon.Framework.Model;
namespace
Downmoon.Framework.Controllers
{
public
class
Factory
{
public
static
IArea GetAreaController()
{
return
AreaList.Instance;
}
}
}
IArea.cs
using
System;
using
System.Collections.Generic;
using
System.Text;
using
Downmoon.Framework.Model;
namespace
Downmoon.Framework.Controllers
{
public
interface
IArea
{
List
<
Area
>
GetAreaList();
List
<
Area
>
GetAreaListFindByParentID(
string
filterID);
}
}
一、基于aspnet自带的Ajax框架,主要好处是与asp.net完全集成,无需写过多的js。缺点是在framework2下需作一些设置,在Framework 4下无需设置。
Framework 2:
需首先在web.config文件中作配置:
<?
xml version="1.0"
?>
<
configuration
>
<
configSections
>
<
sectionGroup
name
="system.web.extensions"
type
="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
>
<
sectionGroup
name
="scripting"
type
="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
>
<
section
name
="scriptResourceHandler"
type
="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
requirePermission
="false"
allowDefinition
="MachineToApplication"
/>
<
sectionGroup
name
="webServices"
type
="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
>
<
section
name
="jsonSerialization"
type
="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
requirePermission
="false"
allowDefinition
="Everywhere"
/>
<
section
name
="profileService"
type
="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
requirePermission
="false"
allowDefinition
="MachineToApplication"
/>
<
section
name
="authenticationService"
type
="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
requirePermission
="false"
allowDefinition
="MachineToApplication"
/>
</
sectionGroup
>
</
sectionGroup
>
</
sectionGroup
>
</
configSections
>
<
system.web
>
<
customErrors
defaultRedirect
=""
/>
<
trace
mostRecent
="true"
pageOutput
="true"
/>
<
pages
>
<
controls
>
<
add
tagPrefix
="asp"
namespace
="System.Web.UI"
assembly
="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
/>
</
controls
>
</
pages
>
<
compilation
>
<
assemblies
>
<
add
assembly
="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
/>
</
assemblies
>
</
compilation
>
<
httpHandlers
>
<
remove
verb
="*"
path
="*.asmx"
/>
<
add
verb
="*"
path
="*.asmx"
validate
="false"
type
="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
/>
<
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"
/>
<
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"
/>
</
httpHandlers
>
<
httpModules
>
<
add
name
="ScriptModule"
type
="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
/>
</
httpModules
>
</
system.web
>
<
system.webServer
>
<
validation
validateIntegratedModeConfiguration
="false"
/>
<
modules
>
<
add
name
="ScriptModule"
preCondition
="integratedMode"
type
="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
/>
</
modules
>
<
handlers
>
<
remove
name
="WebServiceHandlerFactory-Integrated"
/>
<
add
name
="ScriptHandlerFactory"
verb
="*"
path
="*.asmx"
preCondition
="integratedMode"
type
="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
/>
<
add
name
="ScriptHandlerFactoryAppServices"
verb
="*"
path
="*_AppService.axd"
preCondition
="integratedMode"
type
="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
/>
<
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"
/>
</
handlers
>
</
system.webServer
>
</
configuration
>
前台页面:
<
asp:ScriptManager
ID
="ScriptManager1"
runat
="server"
EnablePartialRendering
="true"
>
</
asp:ScriptManager
>
<
div
>
<
asp:UpdatePanel
ID
="UpdatePanel1"
runat
="server"
UpdateMode
="Conditional"
>
<
ContentTemplate
>
<
table
width
="500"
border
="0"
cellpadding
="0"
cellspacing
="2"
>
<
tr
>
<
td
height
="25"
bgcolor
="#EAEAEA"
>
请选择省/市/区:
</
td
>
<
td
bgcolor
="#f7f7f7"
>
<
asp:DropDownList
ID
="dpProvince"
runat
="server"
AutoPostBack
="true"
onselectedindexchanged
="dpProvince_SelectedIndexChanged"
/>
<
asp:DropDownList
ID
="dpCity"
runat
="server"
AutoPostBack
="true"
onselectedindexchanged
="dpCity_SelectedIndexChanged"
/>
<
asp:DropDownList
ID
="dpArea"
runat
="server"
AutoPostBack
="false"
/>
</
td
>
</
tr
>
<
tr
>
<
td
height
="25"
bgcolor
="#EAEAEA"
>
</
td
>
<
td
bgcolor
="#f7f7f7"
>
<
asp:UpdateProgress
ID
="UpdateProgress1"
runat
="server"
>
<
ProgressTemplate
>
正在查询,请稍候……………………
</
ProgressTemplate
>
</
asp:UpdateProgress
>
</
td
>
</
tr
>
</
table
>
</
ContentTemplate
>
<
Triggers
>
<
asp:AsyncPostBackTrigger
ControlID
="dpProvince"
EventName
="SelectedIndexChanged"
/>
<
asp:AsyncPostBackTrigger
ControlID
="dpCity"
EventName
="SelectedIndexChanged"
/>
</
Triggers
>
</
asp:UpdatePanel
>
</
div
>
Framework 4:与代码完全一样,只是无需在web.config中作配置。
如图:
二、基于JQuery1.4.1的Ajax框架,主要好处是与后续版本的asp.net完全集成。
基于ashx作一个Request,主要代码:
using
System;
using
System.Collections.Generic;
using
System.Web;
using
Downmoon.Framework.Controllers;
using
Downmoon.Framework.Model;
using
System.Text;
namespace
dropdown_JQuery14_Net2
{
///
<summary>
///
Summary description for AjaxRequest
///
</summary>
public
class
AjaxRequest : IHttpHandler
{
public
void
ProcessRequest(HttpContext context)
{
string
Area_FatherID
=
string
.Empty;
if
(context.Request[
"
pid
"
]
!=
null
)
{ Area_FatherID
=
context.Request[
"
pid
"
].ToString(); }
string
parentId
=
string
.Empty;
//
mydbDataContext db = new mydbDataContext();
//
根据传过来的Value值 进行查询
//
List<ChinaStates> list = db.ChinaStates.Where(c => c.ParentAreaCode == strId).ToList();
List
<
Area
>
list
=
Factory.GetAreaController().GetAreaListFindByParentID(Area_FatherID);
context.Response.ContentType
=
"
application/json
"
;
context.Response.ContentEncoding
=
Encoding.UTF8;
context.Response.Write(ListToJson(list));
context.Response.End();
}
public
string
ListToJson(List
<
Area
>
list)
{
StringBuilder sb
=
new
StringBuilder();
if
(list
!=
null
)
{
sb.Append(
"
[
"
);
for
(
int
i
=
0
; i
<
list.Count; i
++
)
{
sb.Append(
"
{
"
);
sb.Append(
"
\
"
Area_ID\
"
:\
""
+ list[i].Area_ID +
"
\
"
,
"
);
sb.Append(
"
\
"
Area_Name\
"
:\
""
+ list[i].Area_Name +
"
\
""
);
//
sb.Append("\"Area_FatherID\":\"" + list[i].Area_FatherID + "\"");
if
(i
!=
list.Count
-
1
)
{
sb.Append(
"
},
"
);
}
}
}
sb.Append(
"
}
"
);
sb.Append(
"
]
"
);
return
sb.ToString();
}
public
bool
IsReusable
{
get
{
return
false
;
}
}
}
}
前台:aspx
<!
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
runat
="server"
>
<
title
></
title
>
<
style
type
="text/css"
>
#dpCity
{
display
:
none
;
position
:
relative
;
}
#dpArea
{
display
:
none
;
position
:
relative
;
}
</
style
>
<
script
language
="javascript"
type
="text/javascript"
src
="Scripts/jquery-1.4.1.js"
></
script
>
</
head
>
<
body
>
<
form
id
="form1"
runat
="server"
>
<
div
>
请选择省/市/区:
<
asp:DropDownList
ID
="dpProvince"
runat
="server"
/>
<
asp:DropDownList
ID
="dpCity"
runat
="server"
>
</
asp:DropDownList
>
<
asp:DropDownList
ID
="dpArea"
runat
="server"
AutoPostBack
="false"
/>
</
div
>
<
script
language
="javascript"
type
="text/javascript"
>
$(
function
() {
var
$dp1
=
$(
"
#dpProvince
"
);
var
$dp2
=
$(
"
#dpCity
"
);
var
$dp3
=
$(
"
select[name$=dpArea]
"
);
$dp1.focus();
//
alert($dpCity);
loadAreas(
"
000000
"
,
"
0
"
);
$dp1.bind(
"
change keyup
"
,
function
() {
if
($(
this
).val()
!=
""
) {
//
alert($("select option:selected").val());
//
loadAreas($("select option:selected").val(), "1");
var
strPid
=
$dp1.attr(
"
value
"
);
//
获取城市
loadAreas(strPid,
"
1
"
);
$dp2.fadeIn(
"
slow
"
);
}
else
{
$dp2.fadeOut(
"
slow
"
);
}
});
$dp2.bind(
"
change keyup
"
,
function
() {
var
strCId
=
$dp2.attr(
"
value
"
);
//
获取城市
if
($(
this
).val()
!=
""
) {
loadAreas(strCId,
"
2
"
);
$dp3.fadeIn(
"
slow
"
);
}
else
{
$dp3.fadeOut(
"
slow
"
);
}
});
});
function
loadAreas(selectedItem, level) {
$.getJSON(
"
AjaxRequest.ashx?pid=
"
+
selectedItem,
function
(data) {
switch
(level) {
case
"
0
"
:
$(
"
#dpProvince
"
).html(
""
);
$(
"
#dpProvince
"
).append(
"
<option value='' selected='selected'>请选择...</option>
"
);
for
(
var
i
=
0
; i
<
data.length; i
++
) {
$(
"
#dpProvince
"
).append($(
"
<option></option>
"
).val(data[i].Area_ID).html(data[i].Area_Name));
};
break
;
case
"
1
"
:
$(
"
#dpCity
"
).html(
""
);
$(
"
#dpCity
"
).append(
"
<option value='' selected='selected'>请选择...</option>
"
);
for
(
var
i
=
0
; i
<
data.length; i
++
) {
$(
"
#dpCity
"
).append($(
"
<option></option>
"
).val(data[i].Area_ID).html(data[i].Area_Name));
};
break
;
case
"
2
"
:
$(
"
#dpArea
"
).html(
""
);
$(
"
#dpArea
"
).append(
"
<option value='' selected='selected'>请选择...</option>
"
);
for
(
var
i
=
0
; i
<
data.length; i
++
) {
$(
"
#dpArea
"
).append($(
"
<option></option>
"
).val(data[i].Area_ID).html(data[i].Area_Name));
};
break
;
default
:
break
;
}
});
}
</
script
>
</
form
>
</
body
>
</
html
>
三、基于ExtJS 3.2的Ajax框架。
后台:
using
System;
using
System.Collections.Generic;
using
System.Web;
using
Downmoon.Framework.Controllers;
using
Downmoon.Framework.Model;
using
System.Text;
namespace
dropdown_ExtJS32_Net2.Ajax
{
///
<summary>
///
Summary description for GetAreaXml
///
</summary>
public
class
GetAreaXml : IHttpHandler
{
//
string baseCode = "000000";
public
void
ProcessRequest(HttpContext context)
{
string
parentId
=
"
000000
"
;
if
(context.Request[
"
pid
"
]
!=
null
)
{
parentId
=
context.Request[
"
pid
"
].ToString();
}
//
parentId = (parentId.Length > 0) ? parentId : "000000";
///
/string parentId2 = "000000";
///
/if (context.Request["pid2"] != null)
///
/{
///
/ parentId2 = context.Request["pid2"].ToString();
///
/}
#region
tony 2010.2.7 update
List
<
Area
>
list
=
new
List
<
Area
>
();
//
if (parentId.Length > 0)
//
{
list
=
Factory.GetAreaController().GetAreaListFindByParentID(parentId);
//
}
///
/else if (parentId2.Length > 0)
///
/{
///
/ list = Factory.GetAreaController().GetAreaListFindByParentID(parentId2);
///
/}
#endregion
context.Response.AddHeader(
"
Cache-Control
"
,
"
no-cache, must-revalidate
"
);
context.Response.ContentEncoding
=
System.Text.Encoding.UTF8;
context.Response.ContentType
=
"
text/html
"
;
StringBuilder sb
=
new
StringBuilder();
for
(
int
i
=
0
; i
<
list.Count; i
++
)
{
sb.Append(
"
{\
"
Area_Name\
"
:\
""
+ list[i].Area_Name +
"
\
"
,
"
);
sb.Append(
"
\
"
Area_ID\
"
:\
""
+ list[i].Area_ID +
"
\
"
},
"
);
}
string
json
=
sb.ToString().TrimEnd(
'
,
'
);
context.Response.Write(
"
{\
"
Results\
"
:[
"
+
json
+
"
]}
"
);
}
public
bool
IsReusable
{
get
{
return
false
;
}
}
}
}
前台页面.aspx
<!
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
runat
="server"
>
<
title
>
demo a dropdownlist by extjs 3.2
</
title
>
<
link
rel
="stylesheet"
href
="Scripts/ext/3.2/resources/css/ext-all.css"
/>
<
script
type
="text/javascript"
src
="Scripts/ext/3.2/adapter/ext/ext-base.js"
></
script
>
<
script
type
="text/javascript"
src
="Scripts/ext/3.2/ext-all.js"
></
script
>
<
script
type
="text/javascript"
>
Ext.onReady(
function
() {
//
alert("extjs is Ok!");
});
function
$() {
return
Ext.get(arguments[
0
]);
}
/*
Area
*/
function
GetAreas() {
//
alert($(arguments[1]));
var
cityCtrl
=
$(arguments[
1
]).child(
"
select
"
);
var
cityCtrlContainer
=
$(arguments[
1
]);
cityCtrl.dom.options.length
=
0
;
if
($(arguments[
0
]).getValue()
==
""
) { cityCtrlContainer.hide();
return
; }
cityCtrl.disabled
=
true
;
var
selectValue2
=
$(arguments[
0
]).getValue();
Ext.Ajax.request({
url: arguments[
2
],
params: { pid: selectValue2 },
method:
'
GET
'
,
success:
function
(result, request) {
//
alert(params);
var
jsonData
=
Ext.util.JSON.decode(result.responseText);
//
alert(jsonData.Results.length);
if
(jsonData.Results.length
>
0
) {
cityCtrl.dom.options.add(
new
Option(
"
请选择
"
,
"
000000
"
));
for
(
var
i
=
0
; i
<
jsonData.Results.length; i
++
) {
cityCtrl.dom.options.add(
new
Option(jsonData.Results[i].Area_Name, jsonData.Results[i].Area_ID));
}
cityCtrl.disabled
=
false
;
cityCtrlContainer.show();
}
else
{
cityCtrlContainer.hide();
}
},
failure:
function
(result, request) { Ext.MessageBox.alert(
'
Failed
'
,
'
Successfully posted form:
'
+
action.date); }
});
}
</
script
>
</
head
>
<
body
>
<
form
id
="form1"
runat
="server"
>
<
table
width
="500"
border
="0"
cellpadding
="0"
cellspacing
="2"
>
<
tr
>
<
td
height
="25"
bgcolor
="#EAEAEA"
>
<
div
style
="float: left; height: 20px; line-height: 20px;"
>
请选择
</
div
>
<
asp:DropDownList
Style
="float: left;"
ID
="dropProvince"
runat
="server"
/>
<
div
style
="float: left; height: 20px; line-height: 20px;"
>
省
</
div
>
<
asp:Panel
ID
="panelArea"
runat
="server"
>
<
asp:DropDownList
Style
="float: left;"
ID
="dropArea"
runat
="server"
/>
<
div
style
="float: left; height: 20px; line-height: 20px;"
>
市
</
div
>
</
asp:Panel
>
<
asp:Panel
ID
="panelArea2"
runat
="server"
>
<
asp:DropDownList
Style
="float: left;"
ID
="dropArea2"
runat
="server"
/>
<
div
style
="float: left; height: 20px; line-height: 20px;"
>
县
</
div
>
</
asp:Panel
>
</
td
>
</
tr
>
</
table
>
</
form
>
</
body
>
</
html
>
效果如图:
附源码下载:
下载二
下载一