我最近正在研究小型聊天模块,它需要不断检查服务器是否有新消息。
我正在向服务器发送ajax请求,服务器保持连接,直到找到新消息(长轮询)。
代码:
var chatController = function(){
//other variable declaration
/**
* Ajax call to monitor the new message , on complete of ajax call sending other call
*/
this.checkNewMessage = function(){
console.log(this); // placed this for debugging purpose
$.ajax({
url : SITEURL.CHECK_MESSAGE,
data : this.currrentUserDetails,
dataType : 'json' ,
cache : false,
success :(function(obj){
//temp = obj;
return obj.parseNewMessageResponse;
})(this),
complete: (function(obj){
//temp = obj;
return obj.checkNewMessage;
})(this),
});
};
// other function and variable
});
当我试图打电话时
var mainController = new chatController();
mainController.checkNewMessage();
问题
我的想法是,我可以向服务器发送连续的单个请求,但令我惊讶的是,我只能一个接一个地发送2个ajax请求。
我的调试
当我尝试调试时,我追查到第一个调用this
对象被传递指向chatController
complete: (function(obj){
return obj.checkNewMessage;
})(this), // this here point to chatController object
第二次传递的this
对象指向ajax object
complete: (function(obj){
return obj.checkNewMessage;
})(this), // this here point to ajax object
我正在使用JavaScript闭包将chatController
对象传递给jquery的complete
参数
所以我想要的是将参数传递给jQuery
complete
函数的方法,以便它指向我的原始参考
答案 0 :(得分:6)
$.proxy
:在我看来,最好的做法。
$.ajax({
//...
success: $.proxy(function(json) {
// `this` refers to the second argument of `$.proxy`
}, this)
});
context
option:$.ajax({
//...
context: this,
success: function(json) {
// `this` refers to the value of `context`
}
});
var self = this;
$.ajax({
//...
success: function(json) {
// `this` refers to ajax request, use self instead
$(self).dosomething();
}
});
答案 1 :(得分:2)
至少有四种不同方法可以解决不使用success
和complete
处理程序中的正确上下文调用方法的问题。
使用context
的{{1}}参数,以便成功处理程序中的$.ajax()
将是您想要的,以便您可以调用您的方法。
使用this
创建一个新的函数存根,使用正确的上下文调用您的方法。
将.bind()
的值保存到局部变量中,以便在存根函数中需要时引用该变量。
使用jQuery的this
跨浏览器版本,名为$.proxy()
。
我将为您提供每个例子。
首先,.bind()
的{{1}}选项:
context
然后,使用$.ajax()
。
this.checkNewMessage = function(){
console.log(this); // placed this for debugging purpose
$.ajax({
context: this,
url : SITEURL.CHECK_MESSAGE,
data : this.currrentUserDetails,
dataType : 'json' ,
cache : false,
success : function(data) {
this.parseNewMessageResponse(data);
},
complete : function(data) {
this.checkNewMessage();
}
});
};
然后,使用已保存的.bind()
副本:
this.checkNewMessage = function(){
console.log(this); // placed this for debugging purpose
$.ajax({
url : SITEURL.CHECK_MESSAGE,
data : this.currrentUserDetails,
dataType : 'json' ,
cache : false,
success : this.parseNewMessageResponse.bind(this),
complete : this.checkNewMessage.bind(this)
});
};
最后使用jQuery的`.proxy():
this
如果您不需要IE8支持,或者您可以为this.checkNewMessage = function(){
var self = this;
console.log(this); // placed this for debugging purpose
$.ajax({
url : SITEURL.CHECK_MESSAGE,
data : this.currrentUserDetails,
dataType : 'json' ,
cache : false,
success : function(data) {
self.parseNewMessageResponse(data);
},
complete : function(data) {
self.checkNewMessage();
}
});
};
安装polyfill,那么this.checkNewMessage = function(){
console.log(this); // placed this for debugging purpose
$.ajax({
url : SITEURL.CHECK_MESSAGE,
data : this.currrentUserDetails,
dataType : 'json' ,
cache : false,
success : $.proxy(this.parseNewMessageResponse, this),
complete : $.proxy(this.checkNewMessage, this)
});
};
选项是我的最爱,因为它看起来最干净。
答案 2 :(得分:1)
解决此问题的最简单方法是定义对原始此的引用,以便您可以从其他上下文访问它。看看这个简单的例子:
(function(){
var _self = this;
function changeColor($element, color){
$element.css("background-color", color)
}
$(".recolor-btn").click(function(){
var self = this;
$.ajax({
url: "/Color/GetRandom",
success: function(color){
_self.changeColor($(self), color);
}
});
});
})();