在上一篇文章当中,也就是《以服务器端为中心的 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对 Callback给出正确的调用参数,并在接口方法的实现中接收这些参数然后触发正确的事件,就这么简单。和UpdatePanel一样,不要偏离了ICallbackEventHandler的设计思 想,它的处理流程必须是合并到Page处理流程中的,你的控件也就必须这样设计。
至于在什么情况下选择ICallbackEventHandler?如果你有一个轻量级的Ajax操作 ,但使用UpdatePanel更新整个区域的HTML开销很大的话,那么你可以考虑使用ICallbackEventHandler。当然,前提是你懂得控件开发和JavaScript。