[CallbackPlus]远离UpdatePanel给我的噩梦

本文介绍了一个基于Callback机制的Ajax框架CallbackPlus,旨在解决UpdatePanel在处理庞大页面时带来的性能问题。作者通过反射技术和JSON实现了前后端方法及参数的无缝映射,并提供了示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

********************************************************************
*                                                 版权声明
*
* 本文以Creative Commons的知识共享署名-非商业性使用-相同方式共享发布,请严格遵循该授权协议。
* 本文首发于博客园, 此声明为本文章中不可或缺的一部分。
* 作者网名:    浪子
* 作者EMAILdayichen (at)163.com
* 作者BLOG:  Http://Www.Cnblogs.Com/Walkingboy
*
********************************************************************

[CallbackPlus]远离UpdatePanel给我的噩梦

-Written by 浪子@cnblogs.com  (07-01-09)

摘要:

自从项目要求启用ajax之后,一直都很头痛,直到ComponentArt放出支持ms asp.net ajax之后,所有的问题迎刃而解,于是乎立马down下ms asp.net ajax beta2,祭出神奇的UpdatePanel。但是正所谓“福之祸所依,祸兮福所至”,噩梦已经埋下伏笔......

 

一、噩梦的根源:庞大的页面

UpdatePanel在页面小的时候还是很好用的,而当页面控件数不断上升的时候,UpdatePanel就开始直线下降,我们现在页面有4,5百个控件,每做一次PostBack需要长达15秒钟之长,实在让人无法忍受。

二、救命稻草:ICallbackEventHandler

在实际应用中,我们很多页面同时也使用asp.net 2.0带的Callback机制,发现之间的速度差别不是一般大,那是相当的大阿。于是就萌发利用Callback的机制,制作一个替代UpdatePanel的框架。记得Teddy的AjaxHelper好像是基于Callback实现了,故下载了其框架的范例,发现和自己的想法还是有一定的出入,要直接转移到自己现有的Web框架来,改动量太大,所以,觉得自己写一个这样的框架会更好,不为重复发明轮子,而在于可以减少现有项目重构过程中的改动量。

三、CallbackPlus:

我把这个框架命名为:CallbackPlus,因为其完全是基于Callback机制来做的。

既然基于Callback机制,就有必要了解Callback的运行机制(详见Teddy深度解析Asp.Net2.0中的Callback机制):

 
    
<script language="javascript" type="text/javascript">
function docallback(arg, context)
{
    <%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")%>;    
}
</script>
 
    
<script type="text/javascript">
    function ReceiveServerData(result, context)
    {
         //TODO
    }
</script>

注册调用的script:docallback和接受的script:ReceiveServerData.

CallbackPlus原型就是这么的简单,它的即有功能也就是传递一个string参数,再返回一个string而已。

即然把CallbackPlus命名为一个框架,那似乎不该如此简陋吧,起码也应该把这些个手工注册的烦人工作进行下封装。或许有见过或者使用过Ajax.net的朋友都知道其异步事件的注册方法...嘿嘿,所谓大树底下好乘凉,我也没有必要自己寻找一个方式了,依葫芦画票也使用Attribute来实现(其实我已经深深的爱上了Attribute,哦也,反射,注入......,所有的实现一下子都变大那么的高雅迷人.)

 
    
server:
[CallbackMethod]
public void TestMethod1()
{
    //TODO:
}

 
    
client:
<script>
function doCallback(){
TestMethod1();
}
</scipt>

 在这里通过CallbackMethod的标签将客户端的方法与服务端的方法一一映射起来。

四、Reflect,json让string插上梦想的翅膀:

这样子的功能,实在是不堪大用,只有进一步封装Callback的细节,才可以派上用场。而Callback的实现又是那么的简陋,简陋到只有一个接口ICallbackEventHandler两个方法

 
    
public string GetCallbackResult();
public void RaiseCallbackEvent(string eventArgument);

而当string eventArgument 和return string这两段string结合reflect和json的时候,就可以发挥出不一般的作用。我们可以实现的目标:

  • 让js的方法和cs的方法一一映射
  • 让方法的参数和返回值也一一映射
  • 让js的Object和cs的Class也一一映射

而实现这些的关键所在在于拦截docallback,ICallbackEventHandler的两个方法,ReceiveServerData的调用。关键的js代码:

 
    
<script type=\"text/javascript\">
var CallbackPlus = function(){
return{
    DoCallback:function(target,arg,f,context){
        WebForm_DoCallback(target,arg,f,context,null,true);
    },
    OnCompleted:function(result,f){
        var arguments;
        try{arguments = result.parseJSON();}catch(ex){arguments=result;};
        if(arguments){
         if(arguments[0]){alert(arguments[0]);}; " +
         if(arguments[1]){eval(arguments[1]);};
         if(arguments[2]){
             var obj;
             try{obj = arguments[2].parseJSON();}catch(ex){obj = arguments[2];}
             f.call(this,obj);
         };
        };
    }
};
}();function onCompleted(){};</script>

或许例子更能说明我的意图,请看Demo代码:CallbackPlusDemo.rar

五、后话:

当然这样子的js的取数将成为一个极大的工作量,但是可以在js写一个专门收集form数据的函数,这样子配合CallbackPlus则可实现完全自动的收集数据和更新数据。

目前框架刚刚投入使用,有兴趣的朋友不妨帮忙测试,发现bug希望可以通知我。谢谢

更新 07-01-09 22:10:
更正自己的一个观点:Callback无法取到控件的新的值。

仔细看了下Teddy中文章的讨论,发现Callback照样可以取到控件的新值,真是爽,项目的重构又少了点,不过又担心这个回传是不是会恢复到使用UpdatePanel时候的速度,看来还是需要大页面测试一下.修改CallbackMethod和js增加Postdata的控制设定

None.gif < script type = \ " text/javascript\ " >
ExpandedBlockStart.gifContractedBlock.gif 
var  CallbackPlus  =   function () dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif  
returndot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    DoCallback:
function(target,arg,f,context,isPostdata)dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if(isPostdata)dot.gif{
InBlock.gif        __theFormPostData 
= \"\"
InBlock.gif            __theFormPostCollection 
= new Array(); 
InBlock.gif            WebForm_InitCallback();
ExpandedSubBlockEnd.gif    }
 
InBlock.gif        WebForm_DoCallback(target,arg,f,context,
null,true);
ExpandedSubBlockEnd.gif    }
,
ExpandedSubBlockStart.gifContractedSubBlock.gif    OnCompleted:
function(result,f)dot.gif{
InBlock.gif        
var arguments;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
trydot.gif{arguments = result.parseJSON();}catch(ex)dot.gif{arguments=result;};
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if(arguments)dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif           
if(arguments[0])dot.gif{alert(arguments[0]);}
ExpandedSubBlockStart.gifContractedSubBlock.gif           
if(arguments[1])dot.gif{eval(arguments[1]);}
ExpandedSubBlockStart.gifContractedSubBlock.gif           
if(arguments[2])dot.gif{
InBlock.gif              
var obj;
ExpandedSubBlockStart.gifContractedSubBlock.gif              
trydot.gif{obj = arguments[2].parseJSON();}catch(ex)dot.gif{obj = arguments[2];}
InBlock.gif              f.call(
this,obj);
ExpandedSubBlockEnd.gif           }
;   
ExpandedSubBlockEnd.gif        }
;
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockEnd.gif  }
;
ExpandedBlockEnd.gif}
(); </ script >

转载于:https://www.cnblogs.com/walkingboy/archive/2007/01/09/CallbackPlus.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值