试讲解 ICallbackEventHandler -----无刷新回调------ 希望大家看下是否有错或不妥之处,以免误导。

Jueyoung 2008-06-05 03:19:11
首先感谢sp1234大哥,请见:http://topic.csdn.net/u/20080522/18/687e18b3-54aa-4909-b068-03aa84dc583b.html

[Quote=引用 4 楼 sp1234 的回复:]
问题比较乱,主要是没有点出重点。

1. 使用ICallbackEventHandler 并不需要写一行javascript代码。很可能你看到的“教材”误导了你。使用 GetCallbackEventReference就直接输出了触发客户端回调的代码,就像GetPostEventReference 方法直接输出出发客户端回发的代码一样,无需写一行javascript。

2. 并不是"只要是服务端控件,就一定会提交 刷新页面",原来支持回发的控件与客户端回调根本不冲突。如果你想让imagebutton点击时在后台触发gridview的SelectIndexChanged事件怎么做?把GetPostEventReference 的输出写入imageButton的OnClientClick
属性就行了(如果不放心,后边可以写上 +"return;")。那么同样,让后台触发某个控件的回调,只要使用GetCallbackEventReference输出触发任何目标控件的语句就行了。看来你没有在程序中使用GetPostEventReference 的经历。

3. 必须自己写javascript代码将GetCallbackResult 返回的字符串变为客户端的新界面。简单的做法是可以从字符串中解析出目标控件的UniqueID和html,然后修改html对象的innerHTML属性。不过不是仅仅处理服务器端发过来的html,还要处理服务器端发过来的javascript程序。

4. 之所以很少使用客户端回调,是因为它无法更新ViewState。从而,下一个回调或者回发时,后台得到的页面上某个控件状态都是页面最初被显示时的状态,而不是最近客户端操作的结果。这使得客户端回发不得不废弃,它只是asp.net ajax成熟之前的权宜之计。[/Quote]


虽然知道了,ICallbackEventHandler 接口 用的并不多,而且有更好的 Ajax 技术可以使用, 但自己想弄请这个问题。 毕竟有时候项目要求是不能用 Ajax 的。(客户有时也很怪!)

从 msdn 上 得到 : 需要以下几步 详见 :http://msdn.microsoft.com/zh-cn/library/ms178208(VS.80).aspx#
声明 ICallbackEventHandler 接口
可以将 ICallbackEventHandler 接口作为页的类声明的一部分进行声明。如果创建代码隐藏页,则可以通过使用如下语法声明该接口。


创建服务器回调方法
在服务器代码中,必须创建一个实现 RaiseCallbackEvent 方法的方法和一个实现 GetCallbackResult 方法的方法。RaiseCallbackEvent 方法接受单个字符串参数,而不是通常用于事件处理程序的常见的两个参数。该方法的部分内容可能与下面的代码示例类似。
C#
public void RaiseCallbackEvent(String eventArgument)
{
}

GetCallbackResult 不接受参数并返回一个字符串。该方法的部分内容可能与下面的代码示例类似:
C#
public string GetCallbackResult()
{
return aStringValue;
}

创建客户端脚本函数必须向页中添加客户端脚本函数以执行两个功能:向服务器页发送回调和接收结果。这两个客户端脚本函数都是用 ECMAScript (JavaScript) 编写。

发送回调
发送回调的函数在服务器代码中生成。实际回调由任何页都可使用的、实现 ICallbackEventHandler 接口的库函数执行。通过调用页的 GetCallbackEventReference 方法可以获取对库函数的引用,该方法可通过页 ClientScript 属性进行访问。然后动态生成一个客户端函数,该函数包含对来自 GetCallbackEventReference 方法的返回值的调用。向该方法传递以下内容:对页的一个引用(在 C# 中为 this,在 Visual Basic 中为 Me)、传递数据时所依据的参数名称、将接收回调数据的客户端脚本函数的名称,以及传递所需的任何上下文的参数。

生成函数之后,通过调用 RegisterClientScriptBlock 方法将其插入到页中。

接收回调
可以编写在页中静态接收回调的客户端函数。该函数的名称必须与在 GetCallbackEventReference 方法调用中传递的名称相匹配。接收函数接受两个字符串值:一个用于返回值,另一个(可选)用于从服务器传回的上下文值。

以下,我对应着做一下。并贴出我的代码,有思想不对的地方清指正。 我并不是动态生成的 CallServer 方法 ---??这个方法就是 msdn 所说的 函数调用帮助器方法 么?? 不甚肯定!

声明 ICallbackEventHandler 接口
public partial class _Default : System.Web.UI.Page,System.Web.UI.ICallbackEventHandler


创建服务器回调方法

 string ICallbackEventHandler.GetCallbackResult()
{
// System.Threading.Thread.Sleep(2000);
return CallBackValue + ", C World!";
}

void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
{
this.CallBackValue = eventArgument;
}


创建客户端脚本函数
<script type="text/javascript"> 
function CallServer() // 发送回调
{
var arg = "Cognizant";
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", null)%>;
}

function ReceiveServerData(alertContent) // 接收回调
{
alert(alertContent);
}
</script>



下面把我所有代码贴出来。

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Without Refresh Demo</title>

<script type="text/javascript">
function CallServer()
{
var arg = "Cognizant";
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", null)%>;
}

function ReceiveServerData(alertContent)
{
alert(alertContent);
}
</script>

</head>
<body>
<form id="form1" runat="server">
<div>
<button onclick="CallServer()">HTML Button CallServer</button>
</div>
<div>
<asp:Button ID = "btn1" runat = "server" Text = "ASP:Button" />
</div>
</form>
</body>
</html>


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;

public partial class _Default : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
{
protected void Page_Load(object sender, EventArgs e)
{
btn1.Attributes.Add("onclick", "CallServer();return false;");
}

private string CallBackValue = string.Empty;

#region ICallbackEventHandler Members
string ICallbackEventHandler.GetCallbackResult()
{
// System.Threading.Thread.Sleep(2000);
return CallBackValue + ", C World!";
}

void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
{
this.CallBackValue = eventArgument;
}
#endregion
}




我个人刚进入IT 业没几天, 呵呵, 算是小辈,这里我先说下我的理解。 不对的地方清大家批评! 谢谢!

ICallbackEventHandler 接口有两个方法 RaiseCallbackEvent and GetCallbackResult
通过 Page.GetCallbackEventReference 方法获得对 实现ICallbackEventHandler 接口的库函数 引用

==============
引自msdn
客户端回调组件
创建实现客户端回调的 ASP.NET 页与创建任何 ASP.NET 页类似,但也有如下这些区别。页的服务器代码必须:
实现 ICallbackEventHandler 接口。可以向任何 ASP.NET 网页添加此接口声明。
提供 RaiseCallbackEvent 方法的实现。此方法将被调用以对服务器执行回调。
提供 GetCallbackResult 方法的实现。此方法会将回调结果返回给客户端。

此外,该页还必须包含执行以下操作的三个客户端脚本函数:
一个函数调用帮助器方法,该方法执行对服务器的实际请求。在此函数中,可以首先执行自定义逻辑以准备事件参数,然后可以将一个字符串作为参数发送到服务器端回调事件处理程序.?CallServer?
另一个函数由处理回调事件的服务器代码的结果调用并接收该结果,同时接受表示该结果的字符串。该函数称为客户端回调函数。----- 我想就是我写的 RaiseCallbackEvent
第三个函数是执行对服务器的实际请求的 Helper 函数,当在服务器代码中使用 GetCallbackEventReference 方法生成对此函数的引用时,由 ASP.NET 自动生成该函数.



我的理解是这样:

CallServer --> 获得引用--传参数---〉 调用 RaiseCallbackEvent(String eventArgument) ---- GetCallbackResult----return something --> 客户端回调函数 RaiseServerData。

CallServer 函数 调用回调
我觉得 其中
ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", null)
非常重要
this 是页面的引用,
“arg”-- 传递数据时, 参数的名称 [而非参数]
“ReceiveServerData” -- 将接收回调数据的客户端脚本函数的名称
null -- 传递所需的任何上下文的参数, 这里为 null。


大家可以对照我的代码, 看下, arg 我传个单词 arg 是 名 name 而不是 值 value

function CallServer()
{
var arg = "Cognizant";// 呵呵 违反了保密原则?? 开玩笑, 一个 单词而已嘛!

<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", null)%>;
}


ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", null)
大概意思就是 --- 个人理解:
要告诉服务器 它传了个叫 arg 的参数过来, arg 的值是 Cognizant.
然后, 获得参数 arg 对服务器执行回调
void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
{
this.CallBackValue = eventArgument;
}


然后, 将回调结果返回给客户端
  string ICallbackEventHandler.GetCallbackResult()
{
// System.Threading.Thread.Sleep(2000);
return CallBackValue + ", C World!";
}



 <script type="text/javascript"> 

//...

function ReceiveServerData(alertContent)
{
alert(alertContent);
}

</script>




执行过程大概就是这样, 不对的地方, 还请各位朋友 指出, 欢迎大家讨论下!

贴图

...全文
226 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jueyoung 2008-06-06
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 wdzr_826 的回复:]
ICallbackEventHandler 本质上也是AJAX
[/Quote]
应该不是的吧。
说起本质来, 就不太合适了。
不过只要能理解, 在合适的时后能运用就好。
因为自己碰到了个项目, 严禁使用 ajax , 但又要实现无刷新, 虽然可以用 js, 但我也发现了这个方法。
不知道那个好一些,在以后的工作中体验好了。
谢谢各位关注。
zyug 2008-06-06
  • 打赏
  • 举报
回复
还不如直接js请求webservice或是page,还是与平台无关的.干嘛要学这种于平台有关的呢,
直接js请求
asp也可以用.php也可以用,jsp也可以,对不对
wdzr_826 2008-06-06
  • 打赏
  • 举报
回复
ICallbackEventHandler 本质上也是AJAX
shadowjl 2008-06-06
  • 打赏
  • 举报
回复
mark
scjtswj 2008-06-06
  • 打赏
  • 举报
回复
学习了
Jueyoung 2008-06-06
  • 打赏
  • 举报
回复
留建议者,得分!
andyhooo 2008-06-06
  • 打赏
  • 举报
回复
楼主写的太长了。呵呵。
肖无疾 2008-06-06
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 zyug 的回复:]
还不如直接js请求webservice或是page,还是与平台无关的.干嘛要学这种于平台有关的呢,
直接js请求
asp也可以用.php也可以用,jsp也可以,对不对
[/Quote]
还反扒了
spiritxu 2008-06-05
  • 打赏
  • 举报
回复
继续关注
一品梅 2008-06-05
  • 打赏
  • 举报
回复
收藏
  • 打赏
  • 举报
回复
实际上,如果你需要首先使用客户端回调方法做出一个“ajax框架”,你可以扩展一下你的脚本中的 ReceiveServerData 方法,使得它把 alertContent 参数当作一个javascript命令串来执行(Eval方法),或者从这个字符串中解析出id和html两部分然后动态更新dhtml的内容。然后在后台,自己定义两三个方法,方便包装一些命令或者控件的RenderControl方法输出html成为要输出到 alertContent 的字符串。

不过客户端回调不能维护状态,这个毛病其实挺严重,这使得往往只能最终选择UpdataPanel这种做法。
wxg22526451 2008-06-05
  • 打赏
  • 举报
回复
UP下
图片是XX?
zl58859173 2008-06-05
  • 打赏
  • 举报
回复
学习了。哈哈
amandag 2008-06-05
  • 打赏
  • 举报
回复
慢慢看
Jueyoung 2008-06-05
  • 打赏
  • 举报
回复
自己先沙发下!
欢迎批评指正!

62,074

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧