jQuery pass more parameters into callback
有没有办法将更多数据传递给jQuery中的回调函数?
我有两个函数,我希望回调到
1 2 3 4 5 6 7 8 9 10 11 | 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调用返回的结果。
解决方案是通过闭包绑定变量。
作为一个更基本的例子,这里是一个接收和调用回调函数的示例函数,以及一个示例回调函数:
1 2 3 4 5 6 7 | function callbackReceiver(callback) { callback("Hello World"); } function callback(value1, value2) { console.log(value1, value2); } |
这会调用回调并提供单个参数。现在你想提供一个额外的参数,所以你将回调包装在闭包中。
1 2 3 4 | callbackReceiver(callback); //"Hello World", undefined callbackReceiver(function(value) { callback(value,"Foo Bar"); //"Hello World","Foo Bar" }); |
或者,更简单地使用ES6箭头功能:
1 | callbackReceiver(value => callback(value,"Foo Bar")); //"Hello World","Foo Bar" |
至于你的具体例子,我没有在jQuery中使用
1 | function callBack(data, textStatus, jqXHR) {}; |
因此我认为解决方案如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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"); }; |
怎么了?
在最后一行中,调用
因为
当在返回的
我没有测试过上面的内容,但是我在过去的24小时内编写了非常相似的代码,它的工作原理正如我所描述的那样。
您当然可以传递多个变量而不是单个'extraStuff'对象,具体取决于您的个人偏好/编码标准。
使用
您可以直接传递
如果你想按照它的方式保持doSomething,你可以将它的调用包装在一个匿名函数中。
1 2 3 4 5 6 7 8 9 10 | function clicked() { var myDiv = $("#my-div"); $.post("someurl.php",someData, function(data){ doSomething(data, myDiv) },"json"); } function doSomething(curData, curDiv) { ... } |
在匿名函数代码中,您可以使用封闭范围中定义的变量。这是Javascript作用域的工作方式。
它实际上比每个人都更容易听起来更容易...特别是如果你使用
只需传入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <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); } }); }); |
这比设置var更好的原因之一是var是全局的,因此是可覆盖的...如果你有2个可以触发ajax调用的东西,理论上你可以比ajax调用响应更快地触发它们,你有第二个调用传递给第一个调用的值。使用上面的方法,这不会发生(并且使用它也很简单)。
在今天的世界中,还有另一个更清晰的答案,并取自另一个Stack Overflow答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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如何?将附加参数传递给$ .ajax调用的成功回调?
您还可以尝试以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 | function clicked() { var myDiv = $("#my-div"); $.post("someurl.php",someData,function(data){ doSomething(data, myDiv); },"json"); } function doSomething(curData, curDiv) { } |
您可以使用JavaScript的闭包:
1 2 3 4 5 6 7 | function wrapper( var1, var2,....) // put here your variables { return function( data, status) { //Handle here results of call } }; |
当你能做到:
1 | $.post("someurl.php",data,wrapper(var1, var2, etc...),"html"); |
我们走吧! :)
1 2 3 4 5 6 7 | $.ajax({ url: myUrl, context: $this, // $this == Current $element success: function(data) { $.proxy(publicMethods.update, this)(data); // this == Current $element } }); |
我在上一篇文章中犯了一个错误。这是如何在回调函数中传递其他参数的工作示例:
1 2 3 4 5 6 7 8 9 10 11 | 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; } |
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 2 3 4 5 6 | $('.selector').click(myCallbackFunction.bind({var1: 'hello', var2: 'world'})); function myCallbackFunction(event) { var passedArg1 = this.var1, passedArg2 = this.var2 } |
这里发生了什么,在绑定到回调函数之后,它将在函数中作为
这个想法来自React如何使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | $(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); } |
次要方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 -- } |
对于我和其他刚接触过Javascript的新手,
我认为
虽然我发现了这一点,但您可以使用jquery轻松地将所有参数传递给每个ajax回调。
这是两个更简单的解决方案
@zeroasterisk上面提到的第一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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 ); ... } }); }); |
第二个,通过将自定义数据添加到
它存在于整个ajax-request-response生命周期中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 ); ... } }); }); |
正如您所看到的,这两个解决方案的缺点是:您每次都需要编写更多代码而不仅仅是编写代码:
1 | $.get/post (url, data, successHandler); |
阅读更多关于$ .ajax的信息:http://api.jquery.com/jquery.ajax/
作为b01答案的补充,
1 2 3 4 5 6 7 8 9 10 | 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; } |
此方法还允许将多个参数绑定到回调:
1 2 3 4 5 6 7 8 9 10 11 12 | 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; } |
实际上,你的代码不起作用,因为当你写:
1 | $.post("someurl.php",someData,doSomething(data, myDiv),"json"); |
您将函数调用作为第三个参数而不是函数引用。