我有一个javascript'class',它包含一个调用jquery .ajax()的包装器方法。我想传递onSuccess和onError函数处理程序,但我不知道如何。我可以用简单的旧全局函数来做到这一点,但我正在尝试改进我的javascript(来自Java背景)。任何指针都会受到赞赏。
在下面的_makeAjaxCall()方法中,如何引用onSuccessHandler
function testApp() {
new X();
}
function X() {
// Init X by making Ajax call, passing the func to be called on ajax return
this._makeAjaxCall(initUrl, this.onSuccessInit, this.onError);
// Make another ajax call to init another component
this._makeAjaxCall(initUrl, this.onSuccessSomeOtherAjaxCall, this.onError);
}
X.prototype.onSuccessInit = function(){
this.doStuff(...);
}
X.prototype.onSuccessSomeOtherAjaxCall = function(){
this.doOtherStuff(...);
}
/**
* make an ajax call, and call the provided success/error handler
*/
X.prototype._makeAjaxCall = function(url, onSuccessHandler, onError){
$.ajax({
url : url,
success : function (jsonData, textStatus, XMLHttpRequest) {
// If I don't user 'this', the func called but I've lost my reference
// to my instance of X
onSuccessHandler();
// If I use 'this', it points to the ajax call object, not to my X object.
this.onSuccessHandler();
}
});
}
答案 0 :(得分:1)
问题是当success
函数调用$.ajax
回调时,使用默认上下文window
。你需要告诉JQuery你想要一个不同的上下文,所以你可以做三件事之一:
将上下文属性添加到发送到$.ajax
的哈希,所以我可以这样做:
$.ajax({
url: url,
context: this, // this will tell JQuery to use the right context
success: this.onSuccessHandler
});
使用JQuery的$.proxy
函数,如:
$.ajax({
url: url,
success: $.proxy(this.onSuccessHandler, this) // this will bind the correct context to the callback function
});
缓存变量this
,就像建议的@mVChr一样,虽然我鼓励你使用self
,因为它已成为一种javascript习语
var self = this;
$.ajax({
url: url,
success: function(data) {
self.onSuccessHandler(data);
}
});
编辑:
如果您需要在javascript结帐文章中更深入地解释上下文和范围:http://www.digital-web.com/articles/scope_in_javascript/
答案 1 :(得分:0)
在this
的本地范围内缓存_makeAjaxCall
:
X.prototype._makeAjaxCall = function(url, onSuccessHandler, onError){
var _X = this; // cache this
$.ajax({
url : url,
success : function (jsonData, textStatus, XMLHttpRequest) {
// use cached this
_X.onSuccessHandler();
}
});
}
答案 2 :(得分:0)
感谢CarlosZ& amp ;; mVChr,我已经找到了解决方案http://jsfiddle.net/bX35E/3/
$(document).ready(function testApp() {
new X();
});
function X() {
console.dir(this);
var initUrl = "/echo/json/";
this._instanceVariable = "I AM defined!";
// Init X by making Ajax call, passing the func to be called on ajax return
this._makeAjaxCall(initUrl, this.onSuccessInit(), this.onError);
// Make another ajax call to init another component
this._makeAjaxCall(initUrl, this.onSuccessSomeOtherAjaxCall(), this.onError);
}
X.prototype.onSuccessInit = function(){
//this.doStuff(...);
var self = this;
return function() {
alert("onSuccessInit, _instanceVariable="+self._instanceVariable);
}
}
X.prototype.onSuccessSomeOtherAjaxCall = function(){
var self = this;
return function() {
alert("onSuccessSomeOtherAjaxCall, _instanceVariable="+self._instanceVariable);
}
}