当前位置:首页 > 开发 > Web前端 > Ajax > 正文

Prototype.AjaxRequest的调用堆栈重写问题

发表于: 2006-12-27   作者:cleverpig   来源:转载   浏览:
摘要: Prototype.AjaxRequest的调用堆栈重写问题<o:p></o:p> 作者:cleverpig<o:p></o:p> <o:p> </o:p> 由于调用AjaxRequest类进行XMLHTTPRequest操作时,this引用(指向当前function所在的对象)会出现了call stack问题

Prototype.AjaxRequest的调用堆栈重写问题<o:p></o:p>

作者:cleverpig<o:p></o:p>

<o:p> </o:p>

由于调用AjaxRequest类进行XMLHTTPRequest操作时,this引用(指向当前function所在的对象)会出现了call stack问题,从而指向当前的对象:<o:p></o:p>

错误演示:<o:p></o:p>

var OverWritingDemonstrate=Class.create();<o:p></o:p>

OverWritingDemonstrate.prototype={<o:p></o:p>

    xml_source:'',<o:p></o:p>

    initialize:function(){<o:p></o:p>

    },<o:p></o:p>

    putRequest:function(url,params,callBackFunction){<o:p></o:p>

       var funcHolder=arguments.callee.$;<o:p></o:p>

        var xmlHttp = new Ajax.Request(url,<o:p></o:p>

           {<o:p></o:p>

              method: 'get', <o:p></o:p>

                   parameters: params, <o:p></o:p>

              requestHeaders:['my-header-encoding','utf-8'],<o:p></o:p>

                   onFailure: function(){<o:p></o:p>

                  alert('对不起,网络通讯失败,请重新刷新!');<o:p></o:p>

              },<o:p></o:p>

              onSuccess: function(transport){<o:p></o:p>

              },<o:p></o:p>

              onComplete: function(transport){<o:p></o:p>

                  this.xml_source=transport.responseText;<o:p></o:p>

                  this.showXMLResponse();<o:p></o:p>

              }<o:p></o:p>

           });<o:p></o:p>

    },<o:p></o:p>

    //显示xml信息<o:p></o:p>

    showXMLResponse:function(){<o:p></o:p>

       alert(this.xml_source);<o:p></o:p>

    },<o:p></o:p>

    …<o:p></o:p>

}<o:p></o:p>

这样使用必定找不到showXMLResponse方法,因为在AjaxRequestonComplete函数中的this指向了当前的function所在的对象xmlHttp,而不是我们的OverWritingDemonstrate类对象。<o:p></o:p>

<o:p> </o:p>

Fix方法:<o:p></o:p>

我们可以借鉴一下《解开JavaScript生命的达芬奇密码》Joshua Gertzen的方法,实现一个ClassUtils类:<o:p></o:p>

//类工具<o:p></o:p>

var ClassUtils=Class.create();<o:p></o:p>

ClassUtils.prototype={<o:p></o:p>

    _ClassUtilsName:'ClassUtils',<o:p></o:p>

    initialize:function(){<o:p></o:p>

    },<o:p></o:p>

    /**<o:p></o:p>

     * 给类的每个方法注册一个对类对象的自我引用<o:p></o:p>

     * @param reference 对类对象的引用<o:p></o:p>

     */<o:p></o:p>

    registerFuncSelfLink:function(reference){<o:p></o:p>

       for (var n in reference) {<o:p></o:p>

        var item = reference[n];                        <o:p></o:p>

        if (item instanceof Function) <o:p></o:p>

              item.$ = reference;<o:p></o:p>

    }<o:p></o:p>

    }<o:p></o:p>

}<o:p></o:p>

<o:p> </o:p>

然后修改一下前面的OverWritingDemonstrate,这里为了达到区分效果的目的,类名取为AjaxWrapper<o:p></o:p>

//Ajax操作封装类:<o:p></o:p>

//由于调用AjaxRequest类进行XMLHTTPRequest操作时,this引用(指向当前的对象)会出现了call stack问题,从而指向当前的对象。<o:p></o:p>

//所以,对putRequestcallBackHandler、以及callback方法都要使用arguments.callee.$来获得正确的类对象引用<o:p></o:p>

var AjaxWrapper=Class.create();<o:p></o:p>

AjaxWrapper.prototype={<o:p></o:p>

    xml_source:'',<o:p></o:p>

    /**<o:p></o:p>

     * 初始化<o:p></o:p>

     * @param isDebug 是否显示调试信息<o:p></o:p>

     */<o:p></o:p>

    initialize:function(isDebug){<o:p></o:p>

       new ClassUtils().registerFuncSelfLink(this);<o:p></o:p>

    },<o:p></o:p>

    putRequest:function(url,params,callBackFunction){<o:p></o:p>

       var funcHolder=arguments.callee.$;<o:p></o:p>

        var xmlHttp = new Ajax.Request(url,<o:p></o:p>

           {<o:p></o:p>

              method: 'get', <o:p></o:p>

                parameters: params, <o:p></o:p>

              requestHeaders:['my-header-encoding','utf-8'],<o:p></o:p>

                onFailure: function(){<o:p></o:p>

                  alert('对不起,网络通讯失败,请重新刷新!');<o:p></o:p>

              },<o:p></o:p>

              onSuccess: function(transport){<o:p></o:p>

              },<o:p></o:p>

              onComplete: function(transport){<o:p></o:p>

                  funcHolder.xml_source=transport.responseText;<o:p></o:p>

                  funcHolder.showXMLResponse();<o:p></o:p>

              }<o:p></o:p>

           });<o:p></o:p>

    },<o:p></o:p>

    //显示xml信息<o:p></o:p>

    showXMLResponse:function(){<o:p></o:p>

       alert(funcHolder.xml_source);<o:p></o:p>

    },<o:p></o:p>

    …<o:p></o:p>

}<o:p></o:p>

这样就避免了发生在调用堆栈中的this重写问题了。<o:p></o:p>

<o:p> </o:p>

代码下载:

    demonstrate.rar

相关资源:<o:p></o:p>

   解开JavaScript生命的达芬奇密码<o:p></o:p>

   Prototype JavaScript framework website

   Prototype 快速教学

   Prototype开发手册

Prototype.AjaxRequest的调用堆栈重写问题

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号