[英]passing object to callback function in jquery
我最近正在研究小型聊天模塊,該模塊需要不斷檢查服務器是否有新消息。
我正在向服務器發送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
函數的方法,以便它指向我的原始參考
$.proxy
: 我認為這是最佳做法。
$.ajax({
//...
success: $.proxy(function(json) {
// `this` refers to the second argument of `$.proxy`
}, this)
});
context
選項 : $.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();
}
});
從success
和complete
處理程序中,至少有四種不同的方法可以解決沒有在正確的上下文中調用方法的問題。
使用context
的爭論$.ajax()
使this
在你的成功處理程序將是你希望它是這樣你就可以調用你的方法是什么。
使用.bind()
創建一個新的函數存根,以正確的上下文調用您的方法。
的值保存this
到一個局部變量,所以你可以在你需要它的存根函數引用該變量。
使用jQuery的.bind()
跨瀏覽器版本,稱為$.proxy()
。
我將為您提供每個示例。
首先, $.ajax()
的context
選項:
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)
});
};
然后,使用的保存的副本this
:
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();
}
});
};
最后是jQuery的`.proxy():
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)
});
};
如果不需要IE8支持,或者可以為.bind()
安裝polyfill很好,那么.bind()
選項是我的最愛,因為它看起來最干凈。
解決此問題的最簡單方法是定義對原始this的引用,以便您可以從另一個上下文訪問它。 檢查以下簡單示例:
(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);
}
});
});
})();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.