在项目实践过程中,经常要使用Ajax的方式来处理数据,一般上如果使用js或者jQuery方式来处理,都是需要通过第三方页面来中转,才能达到效果的。当然了,微软本身也为我们提供了一个轻量级的Ajax回调接口:ICallbackEventHandler,通过这个接口,我们不需要通过第三方的中转页面来进行数据请求和处理,直接写到后台即可。下面来说明一下:
首先按照微软官方的说法是,这个接口用于指示控件可以作为服务器上的回调事件的目标。实现它必须要在页面上继承自本接口,然后实现接口中的两个方法:GetCallbackResult()方法和RaiseCallbackEvent()方法。其中前面一个方法主要是返回处理结果,而后面一个方法主要是处理传过来的数据。如何在页面上使用呢?
页面上的引用顺序可以解释如下
1、 在页面前端,需要注册
ClientScript.GetCallbackEventReference(this,"arg","rServer","context")脚本,其中,arg是需要向后台传送的参数,rServer是实现回调后需要处理的函数。Context可以暂时略过。
所以,在前台,一般都这么写:
// 这里处理回调后的结果
}
function raiseEvent(arg, context)
{ // 这里为arg添加参数
<%= ClientScript.GetCallbackEventReference( this , " arg " , " rServer " , " context " ) %> ;
}
这样,注册完事件后,只需要调用raiseEvent()即可。
2、在页面后端,需要继承自ICallbackEventHandler接口,然后实现
RaiseCallbackEvent(string eventArgument)和GetCallbackResult()两个方法,其中前面一个主要是针对前台通过arg传来的参数,进行处理;后面一个主要是将结果返回。
页面调用的图例化调用流程如下:
光说不练,不如不干,下面以两个示例来说明其使用方法,第一个就是通过Ajax聊天室来说明,第二个就通过JQuery的TreeView控件来说明,首先是第一个:
基于ICallBackEventHandler接口的聊天室
首先看成功后的截图:
就是这个效果,具体代码如下:
首先是前台部分,我做了详细的注释:
function checkNick(){
var _val = $( " #txtNick " ).val();
var _say = $( " #txtSay " ).val();
if (_val == "" ) {
alert( " 昵称不能为空! " );
return ;
}
if (_say == "" )
{
alert( " 发言不能为空! " );
return ;
}
}
function rServer(arg, context) {
/* **********************************
这个是回调成功后的处理函数,相当于上面图片流程中的(4),注意,arg参数就是返回的内容
*************************** */
$( " #chartMain " ).html(arg);
}
function raiseEvent(arg, context) {
/* **********************************
本函数主要是发起ajax请求,相当于上面图片流程中的(1),注意,arg参数
*************************** */
checkNick();
arg = $( " #txtNick " ).val() + " | " + $( " #txtSay " ).val();
<%= ClientScript.GetCallbackEventReference( this , " arg " , " rServer " , " context " ) %> ;
}
</ script >
</ head >
< body >
< form id ="form1" runat ="server" >
< div id ="chartMain" ></ div >
< div id ="chartUser" >
< ul >
< li > 请输入昵称: </ li >
< li >< input id ="txtNick" type ="text" /></ li >
< li > 请发言: < input id ="txtSay" type ="text" /></ li >
< li >< input id ="btnSay" type ="button" value ="请你发言" onclick ="raiseEvent();" /></ li ></ ul >
</ div >
</ form >
</ body >
后台部分:
{
public static string str;
protected void Page_Load( object sender, EventArgs e)
{
}
/* ***************
* 这个就是将处理完成的结果返回到前台,相当于图片流程(3)中的秒速
* ******************** */
public string GetCallbackResult()
{
return str;
}
/* ***************
* 这个就是处理的函数,接受前台传过来的arg参数的值,然后进行处理,相当于图片流程(2)所描述
* ********************* */
public void RaiseCallbackEvent( string eventArgument)
{
if ( ! String.IsNullOrEmpty(eventArgument))
{
string [] _str = eventArgument.Split( ' | ' );
string sql = " Insert into ChartInfo values(' " + _str[ 0 ] + " ',' " + _str[ 1 ] + " ',' " + DateTime.Now.ToString() + " ') " ;
int flag = DB.Exec(sql);
string sql1 = " select * from (select top 10 * from ChartInfo order by ID desc) t order by ID asc " ;
using (SqlConnection conn = DB.GetConn())
{
SqlCommand cmd = new SqlCommand(sql1,conn);
SqlDataReader sdr = cmd.ExecuteReader();
StringBuilder sbStr = new StringBuilder();
while (sdr.Read())
{
sbStr.Append( " <br><font color='red'> " + sdr[ " ChartPerson " ].ToString()
}
sdr.Close();
str = sbStr.ToString();
}
}
}
}
基于ICallBackEventHandler接口的大树(TreeView)
在实际项目中,treeview用的是很多的,不论是人员组织关系,还是系统节点显示。可以说TreeView是相当重要的一个控件,今天要介绍的就是利用回调接口实现的JQuery的TreeView,本TreeView是由博客园的假正经哥哥所写的,我这里直接拿来用。
本TreeView主要是采用JSON数据进行组织的,通过页面的节点层次形成了树形结构。在实际使用中,发现很好用,不敢独享,先看下结果:
首先,要说明的是树的形成方式,主要是通过后台取JSON数据组合而成,在页面开始加载的时候,通过页面的RaiseCallBack()方法去调用后台的处理方法。
前台:
$(document).ready( function () {
raiseEvent();
});
function rServer(arg, context) {
var o = { showcheck: true ,onnodeclick:nav }; // 显示checkbox,同时加上节点点击的单击事件:nav();
o.data = eval(arg);
$( " #showTree " ).treeview(o); // 绑定到树上
}
function raiseEvent(arg, context) {
<%= ClientScript.GetCallbackEventReference( this , " arg " , " rServer " , " context " ) %> ;
}
function getValues()
{
var obj = $( " #showTree " );
var thstest = obj.getTSVs(); // 本方法可以获取选取的节点的值
var count = obj[ 0 ].t.getSelectedNodes().length;
var val = obj[ 0 ].t.getSelectedNodes();
for ( var i = 0 ;i < count;i ++ )
{
alert(val[i].text + " - " + val[i].value); // 可以获取选取的节点的值和文本
/* ******************************************************************
当然一点,需要说明的是,如果想向上回溯,可以利用val.parent方法来进行一一查找即可
******************************************************************* */
}
}
function nav(item)
{
$( " #txtNode " ).val(item.text);
}
{
arg = item.text + " - " + item.value;
raiseEvent(arg, "" );
}
</ script >
后台:
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
/* ******************************************************
* 基于ICallbackEventHandler的轻量级ajax回调方法
* 使用方式:首先页面需要继承自ICallbackEventHandler接口
* 然后页面必须实现RaiseCallbackEvent和GetCallbackResult
* 方法,其中注意的是,前面一个函数先被调用,用来接收从前台
* 传送来的数据,后面一个函数是将处理过的函数返回到前台
* *************************************************** */
public partial class _Default : System.Web.UI.Page,ICallbackEventHandler
{
protected void Page_Load( object sender, EventArgs e)
{
}
public string jsonStr = string .Empty;
public string GetJson()
{
string json = " [ " ;
IList < Tree > t = DB.returnParentTree();
foreach (Tree model in t)
{
if (model != t[t.Count - 1 ])
{
json += GetJsonByModel(model) + " , " ;
}
else
{
json += GetJsonByModel(model);
}
}
json += " ] " ;
json = json.Replace( " ' " , " \" " );
return json;
}
public string GetJsonByModel(Tree t)
{
string json = "" ;
bool flag = DB.isHaveChild(t.ModuleID);
json = " { "
+ " 'id':' " + t.ModuleID + " ', "
+ " 'text':' " + t.ModuleName + " ', "
+ " 'value':' " + t.ModuleID + " ', "
+ " 'showcheck':true, "
+ " 'checkstate':'0', "
+ " 'hasChildren': " + flag.ToString().ToLower() + " , "
+ " 'isexpand':false, "
+ " 'ChildNodes': " ;
if ( ! flag)
{
json += " null, " ;
json += " 'complete':false} " ;
}
else
{
json += " [ " ;
IList < Tree > list = DB.getChild(t.ModuleID);
foreach (Tree tree in list)
{
if (tree != list[list.Count - 1 ])
{
json += GetJsonByModel(tree) + " , " ;
}
else
{
json += GetJsonByModel(tree);
}
}
json += " ],'complete':true} " ;
}
return json;
}
public string GetCallbackResult()
{
return jsonStr;
}
public void RaiseCallbackEvent( string eventArgument)
{
jsonStr = GetJson();
}
}
终篇
好了,上面的就是不ICallBackEventHandler接口的一些使用方法,这里主要谈论方法,如果能够正确使用,相信会在项目中发挥出巨大作用的。