в jQuery передать несколько параметров в callback
есть ли способ передать больше данных в функцию обратного вызова в 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.
14 ответов:
решение-это связывание переменных через замыкание.
в качестве более простого примера, вот пример функции, которая получает и вызывает функцию обратного вызова, а также пример функции обратного вызова:
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 Функции:
callbackReceiver(value => callback(value, "Foo Bar")); // "Hello World", "Foo Bar"
что касается вашего конкретного примера, я не использовал тег
.postфункция в jQuery, но быстрое сканирование документации предполагает, что обратный вызов должен быть указатель на функцию со следующей подписью: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он находится в пределах., когда
extraStuffссылается в возвращенной анонимной внутренней функцииdoSomethingон связан замыканием с внешней функцией
при использовании
doSomething(data, myDiv), вы фактически вызываете функцию и не делаете ссылку на нее.вы можете либо передать
это на самом деле проще, чем все это звучит... особенно если вы используете
$.ajax({})базовый синтаксис против одной из вспомогательных функций.просто пройдите в
key: valueпара, как вы бы на любом объекте, когда вы устанавливаете свой запрос ajax... (поскольку$(this)еще не изменил контекст, это все еще триггер для вызова привязки выше)<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 является глобальным и как таковой, перезаписывается... если у вас есть 2 вещи, которые могут вызвать вызовы ajax, вы можете теоретически вызвать их быстрее, чем отвечает вызов ajax, и у вас будет значение для второго вызова, переданного в первый. Используя этот метод, выше, этого не произойдет (и он довольно прост в использовании).
в современном мире есть еще один ответ, который чище, и взят из другого ответа переполнения стека:
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-вызов?
вы также можете попробовать что-то вроде следующего:
function clicked() { var myDiv = $("#my-div"); $.post("someurl.php",someData,function(data){ doSomething(data, myDiv); },"json"); } function doSomething(curData, curDiv) { }
вы можете использовать закрытие 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");
Я сделал ошибку в последнем моем посте. Это рабочий пример того, как передать дополнительный аргумент в функции обратного вызова:
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; }
давайте просто ! :)
$.ajax({ url: myUrl, context: $this, // $this == Current $element success: function(data) { $.proxy(publicMethods.update, this)(data); // this == Current $element } });
более общее решение для отправки асинхронных запросов с помощью
.ajax()jQuery 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); }); };
для меня и других новичков, которые только что связались с Javascript,
Я думаю, чтоCloseure Solution- это немного слишком запутанным.в то время как я обнаружил, что вы можете легко передать столько параметров, сколько хотите для каждого обратного вызова 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-запроса-ответа.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/
Если кто-то еще приходит сюда, это мое мнение:
$('.selector').click(myCallbackFunction.bind({var1: 'hello', var2: 'world'})); function myCallbackFunction(event) { var passedArg1 = this.var1, passedArg2 = this.var2 }что происходит здесь, после привязки к функции обратного вызова, он будет доступен внутри функции как
this.эта идея исходит из того, как React использует
bindфункциональность.
$(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 -- }
на самом деле, ваш код не работает, потому что когда вы пишете:
$.post("someurl.php",someData,doSomething(data, myDiv),"json");вы вызов функции в качестве третьего параметра, а не ссылка на функцию.
в качестве дополнения к B01 не так, второй аргумент
$.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; }
Comments