使用jQuery+HttpHandler+xml模拟一个三级联动的例子
使用jQuery+HttpHandler+xml模拟一个三级联动的例子
发布时间:2016-12-30 来源:查字典编辑
摘要:如下是实现过程:第一步:准备xml文件,并放置在网站根目录下,名为Area.xml复制代码代码如下:第二步:创建与xml文件中定义的元素对应...

如下是实现过程:

第一步:准备xml文件,并放置在网站根目录下,名为Area.xml

复制代码 代码如下:

<?xml version="1.0" encoding="utf-8" ?>

<area>

<province id="1" name="北京">

<city id="1" name="北京">

<county id="1" name="东城区" />

<county id="2" name="西城区" />

</city>

</province>

<province id="2" name="河北省">

<city id="1" name="石家庄市">

<county id="1" name="正定县" />

<county id="2" name="灵寿县" />

</city>

<city id="2" name="邯郸市">

<county id="1" name="邯郸县" />

<county id="2" name="永年县" />

</city>

</province>

<province id="3" name="海南省">

<city id="1" name="海口市">

<county id="1" name="龙华区" />

<county id="2" name="秀英区" />

<county id="3" name="美兰区" />

</city>

<city id="2" name="三亚市">

<county id="1" name="天涯镇" />

<county id="2" name="凤凰镇" />

</city>

</province>

</area>

第二步:创建与xml文件中定义的元素对应的实体类。

<province/>对应province类

复制代码 代码如下:

public class Province

{

private string id;

/// <summary>

/// 编号

/// </summary>

public string Id

{

get { return id; }

set { id = value; }

}

private string name;

/// <summary>

/// 名称

/// </summary>

public string Name

{

get { return name; }

set { name = value; }

}

}

<city/>对应City类:

复制代码 代码如下:

public class City

{

private string id;

/// <summary>

/// 编号

/// </summary>

public string Id

{

get { return id; }

set { id = value; }

}

private string name;

/// <summary>

/// 名称

/// </summary>

public string Name

{

get { return name; }

set { name = value; }

}

}

<county/>对应county类:

复制代码 代码如下:

public class County

{

private string id;

/// <summary>

/// 编号

/// </summary>

public string Id

{

get { return id; }

set { id = value; }

}

private string name;

/// <summary>

/// 名称

/// </summary>

public string Name

{

get { return name; }

set { name = value; }

}

}

第三步:编写服务器端处理程序类:Handler.cs

复制代码 代码如下:

/// <summary>

2 /// 处理程序

3 /// </summary>

4 public class Handler : IHttpHandler

5 {

6

7 private static XDocument doc;

8 private string filePath = HttpContext.Current.Server.MapPath("~/Area.xml");

9 //javascript序列化类

private static JavaScriptSerializer jss = new JavaScriptSerializer();

public void ProcessRequest(HttpContext context)

{

context.Response.ContentType = "text/plain";

string result = "failure";//默认返回结果为失败

HttpRequest req = context.Request;

string province = req["province"];//获取用户选择的省的编号

string city = req["city"];//获取用户选择的市的编号

string county = req["county"];//获取用户选择的县的编号

string type = req["type"];//获取用户需要获取的省市县列表的类型

InitDoc();

if (type.HasValue())

{

switch (type.ToLower())

{

case "province"://如果用户需要获取省级列表

result = jss.Serialize(GetProvinceList());

break;

case "city"://如果用户需要获取的是市级列表

result = jss.Serialize(GetCityListByProvince(province));

break;

case "county"://如果用户需要获取的是县级列表

result = jss.Serialize(GetCountyListByCity(province, city));

break;

default:

break;

}

}

//将结果以文本的格式返回给客户端

context.Response.Write(result);

}

/// <summary>

/// 初始化文档对象

/// </summary>

private void InitDoc()

{

if (doc == null)

{

doc = XDocument.Load(filePath);

}

}

/// <summary>

/// 初始化省级列表

/// </summary>

private List<Province> GetProvinceList()

{

List<Province> list = new List<Province>();

if (doc != null)

{

XElement root = doc.Root;

foreach (var prov in root.XPathSelectElements("province"))

{

list.Add(new Province()

{

Id = prov.Attribute("id").Value,

Name = prov.Attribute("name").Value

});

}

}

return list;

}

/// <summary>

/// 根据省级编号获取市级编号

/// </summary>

/// <param name="provId">省级编号</param>

private List<City> GetCityListByProvince(string provId)

{

List<City> list = new List<City>();

if (doc != null)

{

XElement root = doc.Root;

//xpath表达式:/area/province[@id='1']/city

string queryPath = "/area/province[@id='" + provId + "']/city";

foreach (var city in root.XPathSelectElements(queryPath))

{

list.Add(new City()

{

Id = city.Attribute("id").Value,

Name = city.Attribute("name").Value

});

}

}

return list;

}

/// <summary>

/// 根据省级编号和市级编号获取县级编号

/// </summary>

/// <param name="provId">省级编号</param>

/// <param name="cityId">市级编号</param>

private List<County> GetCountyListByCity(string provId, string cityId)

{

List<County> list = new List<County>();

if (doc != null)

{

XElement root = doc.Root;

string queryPath = "/area/province[@id='" + provId + "']/city[@id='" + cityId + "']/county";

foreach (var county in root.XPathSelectElements(queryPath))

{

list.Add(new County()

{

Id = county.Attribute("id").Value,

Name = county.Attribute("name").Value

});

}

}

return list;

}

public bool IsReusable

{

get

{

return false;

}

}

}

在这里,查询xml我采用的是System.Xml.XPath命名空间下的XPathSelectElements(string xpath)方法和XPathSelectElement(string xpath)方法,在根据省级编号获取市级编号的方法里面,我使用了xpath表达式(假设传入的省级编号为1):/area/province[@id='1']/city,这个表达式以“/”开头,表示使用绝对路径,因为area为根节点所以从area开始,接着它下面有province元素,当我想获取area下所有province元素中id属性值为1的province元素时,我可以使用/area/province[@id='1'],即在province后面加上[@id='1']这个条件,这时我就获取到了area下id属性为1的province元素了。接着我要获取该province元素下所有的city,那么只需在后面加上/city即可,所以最终的xpath表达式为:/area/province[@id='1']/city。

还有,因为此查询的xml是在当前网站的根目录,如果是在其它地方,那么在查询的时候要加上namespace

将从xml文件中读取到的值组装成对应的实体对象只后,我使用了System.Web.Script.Serialization命名空间下的JavaScriptSerializer类中的Serialize方法将得到的实体对象序列化成json数据返回给客户端。

第四步:编写html和js。

复制代码 代码如下:

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>省市县三级联动下拉列表</title>

<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>

<script type="text/javascript">

$(function () {

$.post("/Handler.ashx", { "type": "province" }, function (data, status) {

if (status == "success") {

if (data != "failure") {

data = $.parseJSON(data); //解析服务器返回的json数据

for (var i = 0; i < data.length; i++) {

var value = data[i].Id + ":" + data[i].Name; //设置option选项的值,格式为:"编号:名称"

$("#province").append("<option value='" + value + "'>" + data[i].Name + "</option>");

}

}

}

}, "text");

$("#province").change(function () {

var selectValue = $(this).val(); //获取选择的省级option的值

var provId = selectValue.split(':')[0]; //取出编号

var provTxt = selectValue.split(':')[1]; //取出名称

$("#txtProvince").html(provTxt); //显示选择的省的名称

$("#city").html("<option>==请选择市==</option>"); //当省级改变时将市级清空

$("#county").html("<option>==请选择县==</option>"); //当省级改变时将县级清空

$.post("/Handler.ashx", { "province": provId, "type": "city" }, function (data, status) {

if (status == "success") {

if (data != "failure") {

data = $.parseJSON(data);

for (var i = 0; i < data.length; i++) {

var value = data[i].Id + ":" + data[i].Name;

$("#city").append("<option value='" + value + "'>" + data[i].Name + "</option>");

}

}

}

}, "text");

});

$("#city").change(function () {

var provId = $("#province").val().split(':')[0];

var selectValue = $(this).val(); //同上

var cityId = selectValue.split(':')[0]; //同上

var cityTxt = selectValue.split(':')[1]; //同上

$("#txtCity").html(cityTxt); //显示选择的市的名称

$("#county").html("<option>==请选择县==</option>"); //同上

$.post("/Handler.ashx", { "province": provId, "city": cityId, "type": "county" }, function (data, status) {

if (status == "success") {

if (data != "failure") {

data = $.parseJSON(data);

for (var i = 0; i < data.length; i++) {

var value = data[i].Id + ":" + data[i].Name;

$("#county").append("<option value='" + value + "'>" + data[i].Name + "</option>");

}

}

}

}, "text");

});

$("#county").change(function () {

$("#txtCounty").html($(this).val().split(':')[1]); //显示选择的县的名称

});

});

</script>

</head>

<body>

<>

<select id="province" name="province">

</select>

<>

<select id="city" name="city">

</select>

<>

<select id="county" name="county">

</select>

<br />

<span id="txtProvince"></span>- <span id="txtCity"></span>- <span id="txtCounty"></span>

</body>

</html>

关于使用jQuery与服务器通信,我使用的是$.post方法,该方法的具体使用可以参考jQuery官方文档,这里我想说的是,遍历后通过对象.属性访问时,这个属性的名字是区分大小写的,这个名字是服务器端定义的名字,因为服务器序列化的是服务器端的实体对象。

在这个例子中,关键点就是如何使用XPath表达式,如何调用System.Xml.XPath命名空间下的XPathSelectElements(string xpath)方法。

最终结果如下图:

使用jQuery+HttpHandler+xml模拟一个三级联动的例子1

代码13,31,50行可以优化。

不建议多次修改DOM结构,可以拼接字符串后一次append

数据源是xml,我会用xslt来解析xml直接输出<option>,这样就不用再前台拼接字符串了。要求所有节点ID不能有相同。

复制代码 代码如下:

<select id="province" name="province" next="#city">

</select>

<select id="city" name="city" next="#county">

<option>==请选择市==</option>

</select>

</form>

<select id="county" name="county">

<option>==请选择县==</option>

</select>

<script type="text/javascript">

$("#province,#city").change(function () {

var nextSelect = $(this.getAttribute("next"));

//if (nextSelect.size() > 0) {

nextSelect.find("option:gt(0)").remove();

var _id = $(this).find("option:selected").val();

var query = { parentId: _id };

$.get("/Handler.ashx", query, function (data, status) {

//...

nextSelect.append("<option>...</option>....");

});

//}

});

</script>

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新Javascript教程学习
热门Javascript教程学习
编程开发子分类