您的位置:首页 > 产品设计 > UI/UE

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

2007-05-08 17:02 218 查看
由于调用AjaxRequest类进行XMLHTTPRequest操作时,this引用(指向当前function所在的对象)会出现了call stack问题,从而指向当前的对象:
错误演示:
[align=left]var OverWritingDemonstrate=Class.create();[/align]
[align=left]OverWritingDemonstrate.prototype={[/align]
[align=left] xml_source:'',[/align]
[align=left] initialize:function(){[/align]
[align=left] },[/align]
[align=left] putRequest:function(url,params,callBackFunction){[/align]
[align=left] var funcHolder=arguments.callee.$;[/align]
[align=left] var xmlHttp = new Ajax.Request(url,[/align]
[align=left] {[/align]
[align=left] method: 'get', [/align]
[align=left] parameters: params, [/align]
[align=left] requestHeaders:['my-header-encoding','utf-8'],[/align]
[align=left] onFailure: function(){[/align]
[align=left] alert('对不起,网络通讯失败,请重新刷新!');[/align]
[align=left] },[/align]
[align=left] onSuccess: function(transport){[/align]
[align=left] },[/align]
[align=left] onComplete: function(transport){[/align]
[align=left] this.xml_source=transport.responseText;[/align]
[align=left] this.showXMLResponse();[/align]
[align=left] }[/align]
[align=left] });[/align]
},
[align=left] //显示xml信息[/align]
[align=left] showXMLResponse:function(){[/align]
[align=left] alert(this.xml_source);[/align]
},

}
这样使用必定找不到showXMLResponse方法,因为在AjaxRequest的onComplete函数中的this指向了当前的function所在的对象xmlHttp,而不是我们的OverWritingDemonstrate类对象。

Fix方法:
我们可以借鉴一下《解开JavaScript生命的达芬奇密码》Joshua Gertzen的方法,实现一个ClassUtils类:
[align=left]//类工具[/align]
[align=left]var ClassUtils=Class.create();[/align]
[align=left]ClassUtils.prototype={[/align]
[align=left] _ClassUtilsName:'ClassUtils',[/align]
[align=left] initialize:function(){[/align]
[align=left] },[/align]
[align=left] /**[/align]
[align=left] *给类的每个方法注册一个对类对象的自我引用[/align]
[align=left] *@paramreference对类对象的引用[/align]
[align=left] */[/align]
[align=left] registerFuncSelfLink:function(reference){[/align]
[align=left] for (var n in reference) {[/align]
var item = reference
;
[align=left] if (item instanceofFunction) [/align]
[align=left] item.$ = reference;[/align]
[align=left] }[/align]
[align=left] }[/align]
}
然后修改一下前面的OverWritingDemonstrate,这里为了达到区分效果的目的,类名取为AjaxWrapper:
[align=left]//Ajax操作封装类:[/align]
[align=left]//由于调用AjaxRequest类进行XMLHTTPRequest操作时,this引用(指向当前的对象)会出现了callstack问题,从而指向当前的对象。[/align]
[align=left]//所以,对putRequest、callBackHandler、以及callback方法都要使用arguments.callee.$来获得正确的类对象引用[/align]
[align=left]var AjaxWrapper=Class.create();[/align]
[align=left]AjaxWrapper.prototype={[/align]
[align=left] xml_source:'',[/align]
[align=left] /**[/align]
[align=left] *初始化[/align]
[align=left] *@paramisDebug是否显示调试信息[/align]
[align=left] */[/align]
[align=left] initialize:function(isDebug){[/align]
[align=left] new ClassUtils().registerFuncSelfLink(this);[/align]
[align=left] },[/align]
[align=left] putRequest:function(url,params,callBackFunction){[/align]
[align=left] var funcHolder=arguments.callee.$;[/align]
[align=left] var xmlHttp = new Ajax.Request(url,[/align]
[align=left] {[/align]
[align=left] method: 'get', [/align]
[align=left] parameters: params, [/align]
[align=left] requestHeaders:['my-header-encoding','utf-8'],[/align]
[align=left] onFailure: function(){[/align]
[align=left] alert('对不起,网络通讯失败,请重新刷新!');[/align]
[align=left] },[/align]
[align=left] onSuccess: function(transport){[/align]
[align=left] },[/align]
[align=left] onComplete: function(transport){[/align]
[align=left] funcHolder.xml_source=transport.responseText;[/align]
[align=left] funcHolder.showXMLResponse();[/align]
[align=left] }[/align]
[align=left] });[/align]
},
[align=left] //显示xml信息[/align]
[align=left] showXMLResponse:function(){[/align]
[align=left] alert(funcHolder.xml_source);[/align]
},

}
这样就避免了发生在调用堆栈中的this重写问题了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: