在jquery中将对象传递给回调函数

时间:2014-09-03 06:04:43

标签: javascript jquery ajax

我最近正在研究小型聊天模块,它需要不断检查服务器是否有新消息。

我正在向服务器发送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个a​​jax请求。

我的调试

当我尝试调试时,我追查到第一个调用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函数的方法,以便它指向我的原始参考

3 个答案:

答案 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`
    }
});

或使用closure

var self = this;
$.ajax({
    //...
    success: function(json) {
         // `this` refers to ajax request, use self instead
         $(self).dosomething();
    }
});

答案 1 :(得分:2)

至少有四种不同方法可以解决不使用successcomplete处理程序中的正确上下文调用方法的问题。

  1. 使用context的{​​{1}}参数,以便成功处理程序中的$.ajax()将是您想要的,以便您可以调用您的方法。

  2. 使用this创建一个新的函数存根,使用正确的上下文调用您的方法。

  3. .bind()的值保存到局部变量中,以便在存根函数中需要时引用该变量。

  4. 使用jQuery的this跨浏览器版本,名为$.proxy()

  5. 我将为您提供每个例子。

    首先,.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);
      }
    });
  });

})();