异步回调 之:客户端回调
对于数据量比较大的页面来说,频繁的整体刷新会降低性能以及客户的使用满意度。在客户端使用javascript通过XmlHttp方式调用服务器方法,能够避免在数据回送过程中引发的页面刷新,
客户端回调是实现异步调用局部刷新的一个内置技术,通过简单步骤即可实现。主要在客户端和服务器端做以下操作:
1 客户端:引发回调。向服务器传递参数,启动服务器函数的执行;接受服务器的返回值,修改客户端界面。
2 服务器端:处理回调。接受客户端的回调参数;返回一个新的字符串值给客户端。
回调示例代码
客户端:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<script language=javascript>
function button_click()
{
var args = document.forms[0]['TextBox1'].value;
//CallBack(args,null);
<%= ClientScript.GetCallbackEventReference(this, "args", "GetResultFromServer", "")%>
}
function GetResultFromServer(value, context)
{
alert( value);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
Please input your name: <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<input id="Button2" type="button" value="Aysn Call" onclick="button_click()" />
<br />
<asp:Button ID="Button1" runat="server" Text="Server Button"/>
</div>
</form>
</body>
</html>
button_click函数用于启动回调。必须使用html控件,不能使用Web服务器控件,否则肯定会引起一个新的http post请求,引起页面整体刷新。
ClientScript是ClientScriptManager的一个实例,包含大多是客户端脚本函数。ClientScript.GetCallbackEventReference(this, "args", "GetResultFromServer", "")方法返回一个客户端函数的引用,通过这个方法从客户端调用服务器事件。该函数有多个重写函数,但最终都是调用方法
string target, //处理客户端回调的服务器 Control 的名称。该控件必须实现 ICallbackEventHandler 接口
string argument, //从客户端脚本传递给服务器端的一个参数
string clientCallback, //一个客户端事件处理程序的名称,该处理程序接收成功的服务器端事件的结果
string context, //启动回调之前在客户端计算的客户端脚本。脚本的结果传回客户端事件处理程序。
string clientErrorCallback, //客户端事件处理程序的名称,该处理程序在服务器端事件处理程序出现错误时接收结果
bool useAsync //true 表示同步执行回调;false 表示异步执行回调。
)
{
var args = document.forms[0]['TextBox1'].value;
//CallBack(args,null);
WebForm_DoCallback('__Page',args,GetResultFromServer,"",null,false)
}
GetResultFromServe()接受服务器返回值,并进行客户端操作,如更新界面,从而实现无刷新更新。
服务器端
{
private string _result;
protected void Page_Load(object sender, EventArgs e)
{
//string callRefreence = Page.ClientScript.GetCallbackEventReference(this, "arg", "GetResultFromServer", "context");
//string script = "function CallBack(arg,context){" + callRefreence + "}";
//Page.ClientScript.RegisterStartupScript(this.GetType(), "callback", script, true);
}
public string GetCallbackResult()
{
return "Hello " + _result;
}
public void RaiseCallbackEvent(string eventArgument)
{
if (string.IsNullOrEmpty(eventArgument))
_result = "you input nothing";
else
_result = eventArgument + ", we are from server" ;
}
}
实现ICallbackEventHandler,指示该控件能够作为服务器回调事件的目标控件。该接口提供两个方法:
GetCallbackResult:将结果返回给客户端。返回结果只能是字符串格式,也可以返回Json字符串以方便客户端操作。
RaiseCallbackResult:接受客户端参数,并处理服务器端事物逻辑。
注:在button_click及Page_Load方法中,使用被注释的代码,执行效果相同。
事件调用顺序是:button_click——〉RaiseCallbackEvent——〉GetCallbackResult——〉GetResultFromSever
1 触发客户端回调事件(button_click)
2 服务器端启动回调函数(RaiseCallbackEvent)
3 服务器返回结果到客户端(RaiseCallbackEvent)
4 客户端接受返回值(GetResultFromSever)
5 局部刷新界面(GetResultFromSever里修改界面上控件的值)
通过XmlHttp,从服务器端返回结果后回调客户端方法。当服务器方法执行完后,框架将通知客户端已经执行完毕,然后调用客户端函数(GetResultFromServer)
返回Json值
服务器返回给客户端的结果只能是字符串格式,但是字符串格式的变量处理起来不太方便,我们可以使用Json这一格式化的字符串以方便操作。使用Json功能需要下载Newtonsoft.Json.dll,用来生成Json串。dll文件中的JavaScriptConvert类支持Object对象和Xml对象与Json字符串之间的相互转换。
1 首先定义一个支持序列化的类
public class ObjWithCallBack
{
private string _firstName;
private string _lastName;
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
public ObjWithCallBack()
{ }
}
2 在服务期回调函数中生成Json字符串
{
ObjWithCallBack obj = new ObjWithCallBack();
obj.FirstName = "Guo";
obj.LastName = "Lisa";
_result = JavaScriptConvert.SerializeObject(obj);
}
当然,也可以生成一个XmlDocument对象,使用JavaScriptConvert.SericalizeXmlNode(XmlNode)方法转换Xml。转换后结果:{"FirstName":"Guo","LastName":"Lisa"}
3 客户端使用Json
{
eval(" json = " + value );
alert( json.FirstName + " " + json.LastName);
}
这里要注意的是,由于从服务其传回来的值是字符串型,必须执行eval函数将字符串格式转换成json格式,否则无法通过“.”操作访问。对于xml数据,也通过同样的方式访问,唯一的不同的访问节点属性是要使用@,如json.user.@name。
回调深入分析
回调过程中Page的生命周期,如下图所示:
从上图可以看出,回调过程中并没有出现PreRender、Render事件,页面没有刷新显示。回调过程还可以访问VewState和PostBack Data,但不能保存。
回调是通过XmlHttp完成的,那么这些代码存在于页面的何处呢。查看页面源文件时,可以看到页面有一段脚本:
<script src="/TestWeb/WebResource.axd?d=d1AcIoQReWt2xvw-Cwrp0Q2&t=633783538210457397" type="text/javascript"></script>
通过浏览器可以打开此资源文件,该本件内容全部是javascript,包含了执行回调的所有客户端函数。
局部刷新的详细原理解释,可参照http://www.cnblogs.com/liuxu-wxy/archive/2007/04/25/727346.html,目前自己还没弄明白
参考:
http://www.cnblogs.com/liuxu-wxy/archive/2007/04/25/727346.html
http://blog.csdn.net/cjqpc12345/archive/2006/08/07/1034759.aspx