2009-06-02 49 views
239

有没有办法将更多数据传递到jQuery中的回调函数?jQuery将更多参数传入回调

我有两个功能,我想回调到$.post,例如,在两个AJAX调用的结果数据,以及一些自定义参数传递

function clicked() { 
    var myDiv = $("#my-div"); 
    // ERROR: Says data not defined 
    $.post("someurl.php",someData,doSomething(data, myDiv),"json"); 
    // ERROR: Would pass in myDiv as curData (wrong) 
    $.post("someurl.php",someData,doSomething(data, myDiv),"json"); 
} 

function doSomething(curData, curDiv) { 

} 

我想成为能够将我自己的参数传递给回调函数,以及从AJAX调用返回的结果。

+13

值得一提的是,从1.4版本开始,jQuery.ajax()已经有了一个上下文设置(http://jquery14.com/day-01/jquery-14)在这里可以看到它的用法示例:http:// stackoverflow 。com/questions/5097191/ajax-context-option/5097214#5097214 – russau 2011-10-05 08:34:17

+0

我解决了我的问题,在AJAX完成后返回数据,然后执行某些操作。 – Onaiggac 2017-05-25 18:05:13

回答

323

的解决方案是变量绑定到结束。


作为更基本的例子,这里是接收并调用的回调函数,以及示例回调函数的示例功能:

function callbackReceiver(callback) { 
    callback("Hello World"); 
} 

function callback(value1, value2) { 
    console.log(value1, value2); 
} 

这调用回调并提供一个参数。现在你想提供一个额外的参数,所以你把闭包中的回调。

callbackReceiver(callback);  // "Hello World", undefined 
callbackReceiver(function(value) { 
    callback(value, "Foo Bar"); // "Hello World", "Foo Bar" 
}); 

,或者更简单地使用ES6 Arrow Functions

callbackReceiver(value => callback(value, "Foo Bar")); // "Hello World", "Foo Bar" 

至于你具体的例子,我没有使用jQuery中的.post功能,但文档的快速扫描暗示回电应该是函数指针,并带有以下签名:

function callBack(data, textStatus, jqXHR) {}; 

因此,我认为解决的办法如下:

var doSomething = function(extraStuff) { 
    return function(data, textStatus, jqXHR) { 
     // do something with extraStuff 
    }; 
}; 

var clicked = function() { 
    var extraStuff = { 
     myParam1: 'foo', 
     myParam2: 'bar' 
    }; // an object/whatever extra params you wish to pass. 

    $.post("someurl.php", someData, doSomething(extraStuff), "json"); 
}; 

这是怎么回事?

在最后一行中,doSomething(extraStuff)是调用和调用的结果是一个函数指针

因为extraStuff作为参数传递给doSomething它在doSomething函数的范围内。

当在doSomething的返回匿名内部函数中引用extraStuff时,它被封闭到外部函数的参数extraStuff。即使在doSomething已返回后也是如此。

我还没有测试过上述内容,但是我在过去的24小时内编写了非常类似的代码,它的工作原理与我所描述的一样。

根据您的个人偏好/编码标准,您当然可以传递多个变量而不是单个'extraStuff'对象。

0

实际上,你的代码是不工作,因为当你写:

$.post("someurl.php",someData,doSomething(data, myDiv),"json"); 

您放置函数调用作为第三个参数,而不是一个函数引用

7

您也可以尝试像下面这样:

function clicked() { 

    var myDiv = $("#my-div"); 

    $.post("someurl.php",someData,function(data){ 
     doSomething(data, myDiv); 
    },"json"); 
} 

function doSomething(curData, curDiv) { 

} 
79

使用doSomething(data, myDiv),你实际上调用的函数,不要使对它的引用。

您可以直接传递doStomething函数,但必须确保它具有正确的签名。

如果您想保持原样,可以使用匿名函数包装其呼叫。

function clicked() { 
    var myDiv = $("#my-div"); 
    $.post("someurl.php",someData, function(data){ 
     doSomething(data, myDiv) 
    },"json"); 
} 

function doSomething(curData, curDiv) { 
    ... 
} 

在匿名函数代码中,您可以使用封闭范围中定义的变量。这是Javascript范围工作的方式。

+7

为了清晰起见,这是IMO的最佳解决方案。 `doSomething`函数中没有额外的`return function(...){...}`函数。我在这里发现了另一个相同概念的明显例子:http://theelitist.net/passing-additional-arguments-to-a-callback-function-in-javascript – 2011-10-31 08:28:48

+4

我认为这是一个问题。如果您的额外数据(本例中为myDiv)在回调触发前发生更改,您将获得新值而不是旧值!在我的情况下,我发射了一个数组中的项目的ajax调用,并且在执行第一次success()调用时,它认为它在第一个项目中成功了最后一个项目!布拉德豪斯的答案为我工作。 – Chris 2014-12-09 01:32:16

+0

@Chris是的,捕获的变量可以在Javascript中更改。如果你不想要这种行为,你需要创建一个明确的函数来捕获这个值。最常见的成语是一个自动执行函数`(function(myDiv){...})(myDiv)`来捕获变量`myDiv`。这隐含在@bradhouse答案中完成。 – 2014-12-09 10:23:36

5

您可以使用JavaScript的关闭:

function wrapper(var1, var2,....) // put here your variables 
{ 
    return function(data, status) 
    { 
    //Handle here results of call 
    } 
}; 

,当你可以这样做:

$.post("someurl.php",data,wrapper(var1, var2, etc...),"html"); 
3

我在上一篇文章中犯了一个错误。这是工作例如,对于如何通过在回调函数的附加参数:

function custom_func(p1,p2) { 
    $.post(AJAX_FILE_PATH,{op:'dosomething',p1:p1}, 
     function(data){ 
      return function(){ 
       alert(data); 
       alert(p2); 
      }(data,p2) 
     } 
    ); 
    return false; 
} 
17

在当今世界上是有另一种答案是清洁的,并从另一个堆栈溢出的答案采取:

function clicked() 
{ 
    var myDiv = $("#my-div"); 

    $.post("someurl.php", {"someData": someData}, $.proxy(doSomething, myDiv), "json"); 
} 

function doSomething(data) 
{ 
    // this will be equal to myDiv now. Thanks to jQuery.proxy(). 
    var $myDiv = this; 

    // doing stuff. 
    ... 
} 

这里的原来的问题和答案: jQuery HOW TO?? pass additional parameters to success callback for $.ajax call?

0

作为附录b01's answer$.proxy第二个参数通常被用来保存this参考。传递给$.proxy的其他参数部分应用于该函数,并预填充数据。需要注意的是$.post传递给回调将在年底可应用于任何参数,因此doSomething应该有那些在它的参数列表的末尾:

function clicked() { 
    var myDiv = $("#my-div"); 
    var callback = $.proxy(doSomething, this, myDiv); 
    $.post("someurl.php",someData,callback,"json"); 
} 

function doSomething(curDiv, curData) { 
    //"this" still refers to the same "this" as clicked() 
    var serverResponse = curData; 
} 

这种方法还允许多个参数绑定到回调:

function clicked() { 
    var myDiv = $("#my-div"); 
    var mySpan = $("#my-span"); 
    var isActive = true; 
    var callback = $.proxy(doSomething, this, myDiv, mySpan, isActive); 
    $.post("someurl.php",someData,callback,"json"); 
} 

function doSomething(curDiv, curSpan, curIsActive, curData) { 
    //"this" still refers to the same "this" as clicked() 
    var serverResponse = curData; 
} 
47

它比每个人都听起来更容易...尤其是如果您使用$.ajax({})基本语法与帮手功能之一。

只是通过在key: value对像你将任何物体上,当你设置你的Ajax请求... (因为$(this)没有变化背景下的是,它仍然是上面的bind调用触发)

<script type="text/javascript"> 
$(".qty input").bind("keypress change", function() { 
    $.ajax({ 
     url: "/order_items/change/"+$(this).attr("data-order-item-id")+"/qty:"+$(this).val()+"/returnas.json", 
     type: "POST", 
     dataType: "json", 
     qty_input: $(this), 
     anything_else_i_want_to_pass_in: "foo", 
     success: function(json_data, textStatus, jqXHR) { 
      /* here is the input, which triggered this AJAX request */ 
      console.log(this.qty_input); 
      /* here is any other parameter you set when initializing the ajax method */ 
      console.log(this.anything_else_i_want_to_pass_in); 
     } 
    }); 
}); 
</script> 

这个比设置var更好的原因之一是var是全局的,因此可覆写......如果你有两件事情可以触发ajax调用,你理论上可以触发它们比ajax调用响应,并且您将第二次调用的值传递给第一个调用。在上面使用这种方法,这不会发生(并且它也很简单)。

3

让我们开始吧! :)

$.ajax({ 
    url: myUrl, 
    context: $this, // $this == Current $element 
    success: function(data) { 
     $.proxy(publicMethods.update, this)(data); // this == Current $element 
    } 
}); 
2

发送使用jQuery的.ajax() API和封锁将其他参数传递给回调函数异步请求一个更通用的解决方案:

function sendRequest(method, url, content, callback) { 
    // additional data for the callback 
    var request = { 
     method: method, 
     url: url 
    }; 

    $.ajax({ 
     type: method, 
     url: url, 
     data: content 
    }).done(function(data, status, xhr) { 
     if (callback) callback(xhr.status, data, request); 
    }).fail(function(xhr, status) { 
     if (callback) callback(xhr.status, xhr.response, request); 
    }); 
}; 
1

对于我等新手,谁刚刚接触用Javascript,
我认为Closeure Solution是有点太混乱。

虽然我发现,你可以easilly通过尽可能多的参数,你想每个Ajax回调使用jQuery。

这里有两个更简单的解决方案

首先之一,它@zeroasterisk已如上所述,例如:

var $items = $('.some_class'); 
$.each($items, function(key, item){ 
    var url = 'http://request_with_params' + $(item).html(); 
    $.ajax({ 
     selfDom  : $(item), 
     selfData : 'here is my self defined data', 

     url   : url, 
     dataType : 'json', 
     success  : function(data, code, jqXHR){ 
      // in $.ajax callbacks, 
      // [this] keyword references to the options you gived to $.ajax 
      // if you had not specified the context of $.ajax callbacks. 
      // see http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings context 
      var $item = this.selfDom; 
      var selfdata = this.selfData; 
      $item.html(selfdata); 
      ... 
     } 
    }); 
}); 

第二个,通过将它们添加到XHR object 存在于整个Ajax的请求 - 通过自定义-DATAS响应寿命。

var $items = $('.some_class'); 
$.each($items, function(key, item){ 
    var url = 'http://request_with_params' + $(item).html(); 
    $.ajax({ 
     url   : url, 
     dataType : 'json', 
     beforeSend : function(XHR) { 
      // 为了便于回调,把当前的 jquery对象集存入本次 XHR 
      XHR.selfDom = $(item); 
      XHR.selfData = 'here is my self defined data'; 
     }, 
     success  : function(data, code, jqXHR){ 
      // jqXHR is a superset of the browser's native XHR object 
      var $item = jqXHR.selfDom; 
      var selfdata = jqXHR.selfData; 
      $item.html(selfdata); 
      ... 
     } 
    }); 
}); 

正如你可以看到这两种解决方案的缺点是:你需要每不仅仅是写入时间写一点更多的代码:

$.get/post (url, data, successHandler); 

了解更多关于$阿贾克斯:http://api.jquery.com/jquery.ajax/

1
$(document).on('click','[action=register]',function(){ 
    registerSocket(registerJSON(),registerDone,second($(this))); 
}); 

function registerSocket(dataFn,doneFn,second){ 
       $.ajax({ 
         type:'POST', 
         url: "http://localhost:8080/store/public/register", 
         contentType: "application/json; charset=utf-8", 
         dataType: "json", 
         data:dataFn 
       }).done ([doneFn,second]) 
        .fail(function(err){ 
          console.log("AJAX failed: " + JSON.stringify(err, null, 2)); 
         }); 
} 

function registerDone(data){ 
    console.log(JSON.stringify(data)); 
} 
function second(element){ 
    console.log(element); 
} 

次要方式:

function socketWithParam(url,dataFn,doneFn,param){ 
    $.ajax({ 
    type:'POST', 
    url:url, 
    contentType: "application/json; charset=utf-8", 
    headers: { 'Authorization': 'Bearer '+localStorage.getItem('jwt')}, 
    data:dataFn 
    }).done(function(data){ 
     doneFn(data,param); 
    }) 
    .fail(function(err,status,xhr){ 
    console.log("AJAX failed: " + JSON.stringify(err, null, 2)); 
    }); 
} 

$(document).on('click','[order-btn]',function(){ 
    socketWithParam(url,fakeDataFn(),orderDetailDone,secondParam); 
}); 

function orderDetailDone(data,param){ 
    -- to do something -- 
} 
0

如果有人仍然来到这里,这是我的看法:

$('.selector').click(myCallbackFunction.bind({var1: 'hello', var2: 'world'})); 

function myCallbackFunction(event) { 
    var passedArg1 = this.var1, 
     passedArg2 = this.var2 
} 

这里会发生什么情况,结合回调函数后,它将功能this内面世。

这个想法来自React如何使用bind功能。