说起Ajax,并没有什么特别的感觉,只记得曾经接触过这么几种:
一:Net2.0自带的ICallbackEventHandler
那时候从VS2003刚等到VS2005一出来之际,就看了大量的视频教程,从中也学到了这个ICallback的用法。我将之用在一个CMMI的课程设计里,做的一个图书管理系统,好像在上传图片的时候,为了不刷新某个东东而特意用的。
二:Atlas
只记得很久前,2006还是2007之际。那时的Atlas框架刚出来的时候,我一路追着风。关注的flychen的博客,虽然他的文章多数是翻译。那时候的Atlas很牛B,特效特牛,随便拖一个都是一个赞,我的毕业设计里几乎用上了所有的Atlas控件,就是这份特效为了毕设和第一份工作带来了自信。那时候的毕业设计做的是一个QQ空间,实现的功能就是:主页汇总,日志,留言,音乐盒,相册,换肤,加一个聊天室。那个是一个劲的特效,随便点一个,都忽的一声出来,背景随便就黑屏的那种。什么折叠效果,乱七八糟的,什么音乐盒,还能到处拖。到了后来升到asp.net Ajax版本之后,就再也没那种激情追求什么特效了,把B还给牛了
三:Prototype
在我的毕业设计里,有音乐盒这东西,音乐盒的播放器是从网上下载的。里面用到了一个prototype.js来调用播放列表。于是prototype就成了我的第二个接触的Ajax封装体了,在里面也只是小小用了一下。
四:XMLHttpRequest
还是2007年,要实现一个用户上传图片时,可以拖拉范围红色框同时会放大用户的图片,
用户在一个框选头像后,确定截图上传。
这时用上XMLHttpRequest了,什么新瓶装旧水的言论也略听一二了。
技术总监说这些Ajax早在N年前他就在用了,原理还是Iframe这东西。 后来很多时一直还是用这个。
五:Jquery
这东东我本人没有用过,不过随着它的流行,我在以前兼职教师时,给我学生介绍过,也按着文档实际操作过几个例子,多数还是讲原理的东西。
一路走过来,
从不懂性能[哪个帅点用哪个]->很牛B性能优先[哪个性能最好用哪个]->只有牛,没有B到性能取舍[哪个适合项目用哪个]->没牛也没B这是一个领悟过程
回归是一种自然
下面说下用Net2.0自带的ICallbackEventHandler实现封装的一种应用:省市区的联动实现
首先:新建一个PageBase.cs基类,继承自System.Web.UI.Page和ICallbackEventHandler接口,代码如下:
PageBase.cs
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; /// <summary> /// PageBase 的摘要说明 /// </summary> public class PageBase:System.Web.UI.Page,ICallbackEventHandler{ #region ICallbackEventHandler 成员 /// <summary> /// Ajax方法时的回调结果 /// </summary> public string ajaxCallBackResult = null ; /// <summary> /// 注册Ajax方法 /// 调用方法名:callAjax(arg) /// 回调方法名:callBack(result) /// </summary> public void RegisterAjax() { RegisterAjax( this , " callAjax " , " callBack " ); } public void RegisterAjax(Control ct, string functionName, string callBackName) { if ( ! ct.Page.ClientScript.IsClientScriptBlockRegistered(functionName)) { string callBack = ct.Page.ClientScript.GetCallbackEventReference(ct, " arg " , callBackName, null ); string clientFunction = " function " + functionName + " (arg){ " + callBack + " } " ; ct.Page.ClientScript.RegisterClientScriptBlock(ct.Page.GetType(), functionName, clientFunction, true ); } } public string GetCallbackResult() { return ajaxCallBackResult; } public virtual void RaiseCallbackEvent( string eventArgument) { if (CallAjaxEvenHandle != null ) { CallAjaxEvenHandle(eventArgument); } else { ajaxCallBackResult = eventArgument; } } public delegate void CallAjaxFunction( string para); public event CallAjaxFunction CallAjaxEvenHandle; #endregion }
说明:
上面的基类中封装了一些基础的注册方法,下面演示如何调用。
简单测试调用:
普通页面后台.cs代码,继承自PageBase
public partial class _Default :PageBase{ protected void Page_Load( object sender, EventArgs e) { RegisterAjax(); }}
接着页面html代码如下:
< html xmlns ="http://www.w3.org/1999/xhtml" > < body > < form id ="form1" runat ="server" > < input type ="button" value ="pages" onclick ="callAjax('hello')" /> < script > function callBack(result){alert(result);} </ script > </ form > </ body > </ html >
OK,点击就可以出现hello了。
扩展应用:很多时候,我们需要在用户控件里实现Ajax调用。
这里,也做一个简单调用示例:
控件cs代码:
控件CS代码
public partial class Controls_Head : System.Web.UI.UserControl,ICallbackEventHandler{ string callbackResult; protected void Page_Load( object sender, EventArgs e) { ((PageBase) this .Page).RegisterAjax( this , " callAjaxControl " , " callbackControl " ); } #region ICallbackEventHandler 成员 public string GetCallbackResult() { return callbackResult; } public void RaiseCallbackEvent( string eventArgument) { callbackResult = eventArgument; } #endregion }
用户控件html代码:
控件html代码
<% @ Control Language = " C# " AutoEventWireup = " true " CodeFile = " Head.ascx.cs " Inherits = " Controls_Head " %> < input type ="button" value ="control" onclick ="callAjaxControl('helloControl')" /> < script > function callbackControl(result){alert(result);} </ script >
OK,点击结果也同样出来了。
以下进一步示范怎么实现联动:
过程:1:默认先绑定一个省2:选择省时Ajax请求(发送ID到后台3:后台查询数据库,把省下的市按规则组合发回前台4:前台js按规则拆分字符串5:js清空市并连动区与县的下拉框(或者说叫复位)6:js创建下拉的项option,并添加到市下拉里重复一下就是几级联动了,最后完成
这里的js会做很多事件:发送ajax请求->接收result->分隔字符->复位下拉框->创建下拉option并添加
这里先添加一个AreaCity.js,把上面的东西都实现,代码如下:
AreaCity代码[点下面的一条框出来]
function GetSonData(parentID,sonDropDownID){ if (parentID == " 请选择 " || ! parentID) { SetDropDownToInit(sonDropDownID); } else { callAjax(parentID + " , " + sonDropDownID); }} function callBack(result){ if (result && String(result).indexOf( ' & ' ) >- 1 ) { var listString = result.split( ' & ' )[ 0 ]; var dropDownID = result.split( ' & ' )[ 1 ]; if ( ! listString){SetDropDownToInit(dropDownID)} else {createNode(listString,dropDownID);} }} function createNode(listString ,dropDownID){ var dropDown = $(dropDownID); if ( ! dropDown){ return ;} InitDropDown(dropDown); if (listString) { var strValues = listString.split( ' | ' ); for ( var i = 0 ;i < strValues.length;i ++ ) { var val = strValues[i].split( ' , ' )[ 0 ]; var txt = strValues[i].split( ' , ' )[ 1 ]; var optionObj = document.createElement( " option " ); optionObj.value = val; optionObj.innerText = txt; dropDown.appendChild(optionObj); } dropDown.selectedIndex = 1 ; }} function InitDropDown(dropDown){ while (dropDown.length > 0 ) { dropDown.removeChild(dropDown.firstChild); } var optionObj = document.createElement( " option " ); optionObj.value = '' ; optionObj.innerText = ' 请选择 ' ; dropDown.appendChild(optionObj);} function SetDropDownToInit(dropDownID){ InitDropDown($(dropDownID)); switch (dropDownID) { case " ddlID_City " : InitDropDown($( ' ddlID_County ' )); InitDropDown($( ' ddlID_Town ' )); break ; case " ddlID_County " : InitDropDown($( ' ddlID_Town ' )); break ; }} function $(id){ return document.getElementById(id);}
好,我们先看html代码:引入areacity.cs并拉几个下拉控件上去:
html代码
< html xmlns ="http://www.w3.org/1999/xhtml" > < head runat ="server" > < script src ="js/AreaCity.js" ></ script > </ head > < body > < form id ="form1" runat ="server" > 省: < asp:DropDownList ID ="ddlID_Province" runat ="server" onchange ="GetSonData(this.value,'ddlID_City')" > </ asp:DropDownList >< br /> 市: < asp:DropDownList ID ="ddlID_City" runat ="server" onchange ="GetSonData(this.value,'ddlID_County')" > < asp:ListItem Text ="请选择" ></ asp:ListItem ></ asp:DropDownList >< br /> 区: < asp:DropDownList ID ="ddlID_County" runat ="server" onchange ="GetSonData(this.value,'ddlID_Town')" > < asp:ListItem Text ="请选择" ></ asp:ListItem ></ asp:DropDownList >< br /> 镇: < asp:DropDownList ID ="ddlID_Town" runat ="server" > < asp:ListItem Text ="请选择" ></ asp:ListItem > </ asp:DropDownList > </ form > </ body > </ html >
现在看一下后台代码cs,这里不用数据库,临时用Dic字典组合充当数据:
cs代码
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Collections.Generic; using System.Collections; public partial class ProvinceCity : PageBase{ protected void Page_Load( object sender, EventArgs e) { if ( ! IsPostBack) { RegisterAjax(); // 一开始绑定省 ddlID_Province.DataSource = GetChild( 0 ); ddlID_Province.DataValueField = " key " ; ddlID_Province.DataTextField = " value " ; ddlID_Province.DataBind(); ddlID_Province.Items.Insert( 0 , " 请选择 " ); } } public override void RaiseCallbackEvent( string eventArgument) { if (eventArgument.Contains( " , " )) { string parentID = eventArgument.Split( ' , ' )[ 0 ]; // 根据ID查数据库 Dictionary < int , string > items = GetChild( int .Parse(parentID)); if (items.Count > 0 ) { foreach (KeyValuePair < int , string > itemPair in items) { ajaxCallBackResult += itemPair.Key + " , " + itemPair.Value + " | " ; } ajaxCallBackResult = ajaxCallBackResult.TrimEnd( ' | ' ); } ajaxCallBackResult += " & " + eventArgument.Split( ' , ' )[ 1 ]; // 附加回去下拉列表控件ID } } #region 假设这里为数据库查询 protected Dictionary < int , string > GetChild( int parentID) { Dictionary < int , string > items = new Dictionary < int , string > (); switch (parentID) { case 0 : items.Add( 1 , " 广东省 " ); items.Add( 2 , " 广西省 " ); break ; case 1 : items.Add( 11 , " 汕尾市 " ); items.Add( 12 , " 广州市 " ); break ; case 2 : items.Add( 21 , " 桂林市 " ); items.Add( 22 , " 南宁市 " ); break ; case 11 : items.Add( 111 , " 海丰县 " ); break ; case 12 : items.Add( 121 , " 天河区 " ); break ; case 111 : items.Add( 1111 , " 城东 " ); items.Add( 1112 , " 城西 " ); break ; } return items; } #endregion }
至此,下拉效果就出来了。
示例代码下载: