簡體   English   中英

在jQuery中將對象傳遞給回調函數

[英]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();
    }
});

successcomplete處理程序中,至少有四種不同的方法可以解決沒有在正確的上下文中調用方法的問題。

  1. 使用context的爭論$.ajax()使this在你的成功處理程序將是你希望它是這樣你就可以調用你的方法是什么。

  2. 使用.bind()創建一個新的函數存根,以正確的上下文調用您的方法。

  3. 的值保存this到一個局部變量,所以你可以在你需要它的存根函數引用該變量。

  4. 使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM