【问题标题】:passing object to callback function in jquery将对象传递给jQuery中的回调函数
【发布时间】:2014-09-03 06:04:42
【问题描述】:

我最近在做一个小聊天模块,需要不断检查服务器是否有新消息。

我正在向服务器发送一个 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 函数的方法,以便它指向我的原始参考

【问题讨论】:

  • 您可以将“this”定义为变量然后使用它。像 var $thisChatController = this;
  • @SohilDesai 能给我举个例子吗,谢谢
  • @Parfait 我想在回调中传递相同的对象函数
  • 您可以使用 Signal R 来实现它,这是 .net codeproject.com/Articles/524066/… 中的聊天应用程序示例,如果您使用其他语言,您也可以将其集成......

标签: javascript jquery ajax


【解决方案1】:

有多种可能的 解决方案

你可以使用$.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();
    }
});

【讨论】:

    【解决方案2】:

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

    1. $.ajax() 使用context 参数,这样您的成功处理程序中的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() 选项,因为它看起来最干净。

    【讨论】:

      【解决方案3】:

      解决此问题的最简单方法是定义对原始 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);
            }
          });
        });
      
      })();
      

      【讨论】:

        猜你喜欢
        • 2012-09-12
        • 2015-12-16
        • 1970-01-01
        • 1970-01-01
        • 2018-04-07
        • 1970-01-01
        • 2016-09-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多