用回调实现的省市县区四级下拉选择联动的例子

本文示例代码(52K),请在VS2005中用"打开网站"的方式打开并运行
demo.jpg
上个月贴过一个用回调实现的下拉列表联动的例子,不过那个示例相对简单,只阐述了概念,离实际的运用还有距离,今天再贴一个用回调实现的地区选择的例子,不附加任何第三方DLL,数据库也用最基本的Access构成,可以方便的转换成其它数据库,喜欢的朋友可以方便的转为己用。

闲话少说,先看下回调的关键部分,Javascript部分是发起回调,并接收返回的结果

None.gif function  OnProvinceChanged()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    dot.gifdot.gif
InBlock.gif    
//  控制一个ID为td_cities的<td>内部控件的更新
InBlock.gif
    var context = document.getElementById("td_cities");
InBlock.gif    
var theDDL_Province = document.getElementById("DropDownList_Provinces");        
InBlock.gif    
//  调用服务器方法UpdateCities,并将DropDownList_Provinces当前选择的value传过去
InBlock.gif
     var arg = "UpdateCities|" + theDDL_Province.value;
InBlock.gif        
InBlock.gif    
<%= ClientScript.GetCallbackEventReference(this"arg""UpdataDropDownList_Cities""context"%>;
ExpandedBlockEnd.gif}

None.gif
None.gif
//   接收回调后服务器传回的结果,这里是DropDownList_Provinces控件重新绑定后的HTML编码
None.gif
function  UpdataDropDownList_Cities(result, context)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
//  控件的前台"更新"
InBlock.gif
    context.innerHTML = result;    
ExpandedBlockEnd.gif}
在Javascript中调用服务器端方法可能不止一个参数,此时arg的构成格式为:"服务器方法名" + "|" + "参数1" + "|" + "参数2" + ... 需要说明的是,这里的服务器方法必须是public的,接收的参数均为string类型,否则会出错。再看下服务器端三个核心的方法:
ContractedBlock.gif ExpandedBlockStart.gif 回调实现,固定的写法 #region 回调实现,固定的写法
InBlock.gif
public string str_content;
InBlock.gif
InBlock.gif
//  接收Javascript传过来的arg为the_string
InBlock.gif
public void RaiseCallbackEvent(string the_string)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    str_content 
= the_string;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
//  根据arg构造参数序列并调用服务器端方法
InBlock.gif
public string GetCallbackResult()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    
//  拆分由客户端传过来的参数
InBlock.gif
    string[] parts = str_content.Split('|');
InBlock.gif
InBlock.gif    
//  生成ServerMethod的参数队列
InBlock.gif
    object[] theArgList = new object[parts.Length - 1];
InBlock.gif    
for (int int_index = 1; int_index < parts.Length; int_index++)
InBlock.gif        theArgList[int_index 
- 1= parts[int_index];
InBlock.gif
InBlock.gif    
//  调用ServerMethod
InBlock.gif
    return (string)GetType().GetMethod(parts[0]).Invoke(this, theArgList);
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
//  返回指定控件的HTML编码
InBlock.gif
private string RenderControl(Control control)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    StringWriter writer1 
= new StringWriter(CultureInfo.InvariantCulture);
InBlock.gif    HtmlTextWriter writer2 
= new HtmlTextWriter(writer1);
InBlock.gif
InBlock.gif    control.RenderControl(writer2);
InBlock.gif    writer2.Flush();
InBlock.gif    writer2.Close();
InBlock.gif
InBlock.gif    
return writer1.ToString();
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif
#endregion
其中前两个方法可以在实现ICallbackEventHandler接口时由代码提示辅助生成,ICallbackEventHandler的namespace为System.Web.UI.ICallbackEventHandler,为了使用方法RenderControl中的StringWriter及CultureInfo还必须在文件头添加对他们的引用
None.gif using  System.Web.UI;
None.gif
using  System.IO;
None.gif
using  System.Globalization;
服务器端对下拉控件的更新如下,相对正常的绑定只做了很小的更改
None.gif //   更新地级市
None.gif
public   string  UpdateCities( string  str_ProvinceID)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
return UpdateDropDownList(str_ProvinceID, DropDownList_Cities);
ExpandedBlockEnd.gif}

None.gif
None.gif
//   根据上级编号更新指定的DropDownList
None.gif
private   string  UpdateDropDownList( string  str_parent_id, DropDownList theDropDownList)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
string str_SQL = "Select area_id, area_name From Cities Where area_parent_id = '" + str_parent_id + "' Order By area_id Asc";
InBlock.gif
InBlock.gif    DataTable theDataTable 
= GetDataTable(str_SQL);
InBlock.gif
InBlock.gif    
if (theDataTable == null)
InBlock.gif        
return string.Empty;
InBlock.gif
InBlock.gif    
//  数据绑定
InBlock.gif
    theDropDownList.DataSource = theDataTable;
InBlock.gif    theDropDownList.DataTextField 
= "area_name";
InBlock.gif    theDropDownList.DataValueField 
= "area_id";
InBlock.gif    theDropDownList.DataBind();
InBlock.gif
InBlock.gif    
//  返回的是Javascript便于处理的string
InBlock.gif
    if (str_parent_id == "000000")
InBlock.gif        
//  省级列表不需要联动
InBlock.gif
        return string.Empty;
InBlock.gif    
else
InBlock.gif        
return RenderControl(theDropDownList);
ExpandedBlockEnd.gif}

4个下拉列表的联动需要涉及到3次回调过程,限于微软在回调JS端的代码BUG,这3次回调只能用串联进行,中间用setTimeout()连接,否则会有Javascript报错,这也算是回调的一大缺陷吧。
Access中表Ctities的组织如下,area_parent_id顾名思义是该地区上级地区的编码,省级的上级是000000,这里我收集了3523条记录,基本涵盖了大江南北
data.jpg
更细节的地方还是在示例代码中找答案吧。

回调说到底还是微软对xmlhttp对象操作的封装,和其它Ajax实现大同小异,微软制定了固定的流程套路来降低Ajax的开发门槛,不用额外第三方DLL的支持是其最大的亮点,因此可以稳定在各支持ASP2.0的Server上运行,当然,回调并不是ASP2.0独有的,在ASP1.1时就已存在。

转载于:https://www.cnblogs.com/jhobo/archive/2006/08/17/479474.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值