.net ajax 服务器,以服务器端为中心的 ASP.NET AJAX 模式(2)-陈广琛 | Microsoft Docs

以服务器端为中心的 ASP.NET AJAX 模式 (Part 2 - Control)

01/05/2009

本文内容

作者:陈广琛

在上一篇文章当中,也就是《以服务器端为中心的 ASP.NET AJAX 模式 (Part 1 - Behavior)》,我们探讨了较为易用的 Behavior模式。之所以说它较为易用,是因为它不涉及和原有 Page处理流程的交互,即使访问网络也是访问独立的 Web Service(包括 Page上的 [WebMethod]),因此和 Page处理流程的设计绝对是正交的。但有时候我们需要的就是与 Page处理流程的交互,这时我们不得不使用与服务器端逻辑紧耦合的 Control了,这正是本次文章要讨论的内容。

在基本的 ASP.NET AJAX框架下,我们有三种方法来做基于 Control的 Ajax操作,它们分别是 UpdatePanel、 ICallbackEventHandler和 IScriptControl,下面我们就分别看看它们的特点和使用场景。

UpdatePanel

UpdatePanel是与服务器端逻辑进行交互的多种方案中最易用的一个,甚至就不能称之为交互 ——你根本就不需要触及任何客户端逻辑。一个服务器端操作,经过 UpdatePanel的 “劫持 ”,变成了一个客户端操作,而这个客户端操作又直接调用对应的服务器端操作,就这么简单。

如果用 UpdatePanel来做一个带分支的选择对话框,那应该如何设计?思路可别跑到客户端的 confirm方法上去,那可太绕了,或者说太不 ASP.NET AJAX了。用 UpdatePanel,就应该坚持它的理念,一切客户端操作都是幻象,所有操作其实都是在服务器端进行的,包括选择对话框。要按 ASP.NET的思路来做,我会做一个选择对话框控件,它的实质可能是一个浮动层模拟的对话框,这属于实现细节,我们不用太关注。重点是,这个选择对话框的分支逻辑是完全在服务器端进行的, Async PostBack之后服务器端根据提交回来的数据决定如何触发事件。这样做整个分支选择的逻辑就是内嵌在 Page处理流程当中的,不需要通过 Cookies或者 Session来做数据的中转媒介,避免了 Page处理流程与更大作用域中的数据的紧耦合。

UpdatePanel适用于逻辑完全在服务器端的开发,并且我建议使用 UpdatePanel时也就把所有逻辑放在服务器端,不要去写一些混合服务器端逻辑与客户端逻辑的代码。有人会说,你看老赵就很喜欢去动那个 Sys.Net.WebRequestExecutor来改变 UpdatePanel的行为啊,但其实这属于分层设计思想中的一部分,他去动那个东西改变的也就是一个分层内的逻辑,只要层与层之间的接口不变,具体实现是可以按需设计的。但如果你用了 UpdatePanel,同时又用 Cookies或者 Session来传值,这就跨越了 n个层,增加了不少耦合度。

ICallbackEventHandler

关于 ICallbackEventHandler,我已经说过无数次了,重点还是你必须用 Page处理流程来思考,只要你理解了 Page处理流程,你就明白为什么 ICallbackEventHandler在 .NET Framework 2.0 Beta2中只有一个方法,而到了 RTM要分拆成两个方法。具体可以参考《ASP.NET 2.0 ClientScript Callback》,我就不再重复了。

如果用 ICallbackEventHandler实现一个带分支的选择对话框,又如何做?和使用 UpdatePanel的做法类似,我还是会做一个选择对话框控件,并且这个控件继承自 ICallbackEventHandler。为这个控件编写 JavaScript并实现 ICallbackEventHandler接口时,我会确保 JavaScript对 Callba ck给出正确的调用参数,并在接口方法的实现中接收这些参数然后触发正确的事件,就这么简单。和 UpdatePanel一样,不要偏离了 ICallbackEventHandler的设计思想,它的处理流程必须是合并到 Page处理流程中的,你的控件也就必须这样设计。

至于在什么情况下选择 ICallbackEventHandler?如果你有一个轻量级的 Ajax操作,但使用 UpdatePanel更新整个区域的 HTML开销很大的话,那么你可以考虑使用 ICallbackEventHandler。当然,前提是你懂得控件开发和 Ja vaScript。

IScriptControl

这是最复杂的解决方案了,你需要实现一个 Control的两个副本 ——一个服务器端的,一个客户端的。有一部分逻辑,是要在客户端和服务器端重复实现两次的,而另外一部分逻辑,只需要在客户端或服务器端之中的一个实现一次。 IScriptControl的经典例子,当然是 ASP.NET AJAX自带的 Timer控件。它的计时器是纯粹的客户端逻辑,然而 Tick事件却在服务器端触发, Async PostBack成为了两者之间的桥梁。当然,就 Control本身而言,它并不在乎 Po stBack是不是异步的, Tick事件只因 PostBack而触发。

如果用 IScriptControl来实现带分支的选择对话框,那将会和 ICallbackEventHandler的版本十分相似,唯一不同的地方就是它在客户端的逻辑会被封装为一个 Sys.UI.Control的派生类,而 ICallbackEventHandler的客户端逻辑往往是不封装的。这样的好处显而易见,那就是代码更容易维护了,并且客户端的 Control可以同样可以加入事件支持,并提供和服务器端一样的代码分支事件。要知道在 CTP阶段的 Time r控件,其客户端版本 Sys.Timer(而非 RTM的 Sys.UI._Timer)是拥有 tick事件的,和服务器端的 Tick事件对应,只不过 RTM取消了此项功能,因为 ASP.NET AJAX 1.0的侧重点完全就是服务器端功能,客户端功能都被砍掉了。

什么情况下选用 IScriptControl?如果你认为你的客户端逻辑应该封装为 Sys.UI.Control的派生类,那就选择 IScriptControl吧。

小结

我们分别讨论了三种通过 Control实现 Ajax调用的方案,并且一再强调了设计必须基于 Page处理流程,不要在此流程之外增加不必要的复杂度和耦合度。值得一提的是,有很多人质疑为什么要在 Web上提供这样一个支持分支的选择对话框功能,我的看法是这样的:既然客户端软件的流程会有此功能,那么 Web应用也有此功能就实在是太正常了,你删除 blog post的时候问你一下是否确认删除,难道会有人觉得这个功能是设计错误?可能不同的只是表现形式而已,到底是 confirm还是弹出层,甚至是一个专用的过渡页面。然而从用户体验的角度来说,这其实并不是最优的方案,多数时候用户删除就是确认删除,并不需要再问一次是否确认之类的愚蠢问题,但开发人员觉得用户错手删除的后果应当由用户自己承担,所以就做了这样一个对话框来推卸责任。真正好的用户体验是不需要确认的删除,但用户一定能够恢复,最好是按一下 Ctrl+Z就可以了,然而对于开发人员来说还是有很多操作是无法做到可恢复的,这时候除了显示对话框也没有更好的解决方案了。

最后,如果你喜欢我的文章,可以通过订阅 feed来及时获得更新:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值