una - pasar parametros javascript onclick
jQuery pasar más parámetros en devolución de llamada (14)
¿Hay alguna forma de pasar más datos a una función de devolución de llamada en jQuery?
Tengo dos funciones y quiero que la devolución de llamada a $.post
, por ejemplo, pase tanto los datos resultantes de la llamada AJAX, como algunos argumentos personalizados.
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) {
}
Quiero poder pasar mis propios parámetros a una devolución de llamada, así como el resultado devuelto de la llamada AJAX.
¡Vamos simples! :)
$.ajax({
url: myUrl,
context: $this, // $this == Current $element
success: function(data) {
$.proxy(publicMethods.update, this)(data); // this == Current $element
}
});
Al usar doSomething(data, myDiv)
, realmente llama a la función y no hace referencia a ella.
Puede pasar la función doStomething
directamente, pero debe asegurarse de que tenga la firma correcta.
Si desea mantener doAlgo como es, puede ajustar su llamada en una función anónima.
function clicked() {
var myDiv = $("#my-div");
$.post("someurl.php",someData, function(data){
doSomething(data, myDiv)
},"json");
}
function doSomething(curData, curDiv) {
...
}
Dentro del código de función anónima, puede usar las variables definidas en el ámbito adjunto. Esta es la forma en que funciona el alcance de Javascript.
Como una adición a la respuesta de b01 , el segundo argumento de $.proxy
se usa a menudo para preservar this
referencia. Los argumentos adicionales pasados a $.proxy
se aplican parcialmente a la función, $.proxy
previamente con datos. Tenga en cuenta que todos los argumentos que pasa $.post
a la devolución de llamada se aplicarán al final, por lo que doSomething
debe tener esos al final de su lista de argumentos:
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;
}
Este enfoque también permite vincular múltiples argumentos a la devolución de llamada:
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;
}
En el mundo de hoy hay otra respuesta que es más limpia y que se toma de otra respuesta de desbordamiento de pila:
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.
...
}
Aquí está la pregunta y la respuesta original: jQuery CÓMO? ¿Pasar parámetros adicionales a devolución de llamada exitosa para $ .ajax call?
En realidad, es más fácil que todo el mundo lo hace sonar ... especialmente si usa la sintaxis básica $.ajax({})
comparación con una de las funciones de ayuda.
Simplemente pase la key: value
par de key: value
como lo haría en cualquier objeto, cuando configure su solicitud ajax ... (porque $(this)
aún no ha cambiado el contexto, sigue siendo el desencadenante de la llamada de enlace anterior)
<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>
Una de las razones por las que esto es mejor que establecer la var, es que la var es global y, como tal, se puede sobrescribir ... si tiene 2 cosas que pueden activar llamadas ajax, en teoría podría dispararlas más rápido de lo que responde la llamada ajax, y Usted tendría el valor para la segunda llamada pasada a la primera. Usando este método, arriba, eso no sucedería (y es bastante simple de usar también).
He cometido un error en la última de mis publicaciones. Este es un ejemplo práctico de cómo pasar un argumento adicional en la función de devolución de llamada:
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;
}
La solución es la unión de variables mediante cierre.
Como un ejemplo más básico, aquí hay una función de ejemplo que recibe y llama a una función de devolución de llamada, así como una función de devolución de llamada de ejemplo:
function callbackReceiver(callback) {
callback("Hello World");
}
function callback(value1, value2) {
console.log(value1, value2);
}
Esto llama a la devolución de llamada y proporciona un solo argumento. Ahora desea proporcionar un argumento adicional, por lo que envuelve la devolución de llamada en el cierre.
callbackReceiver(callback); // "Hello World", undefined
callbackReceiver(function(value) {
callback(value, "Foo Bar"); // "Hello World", "Foo Bar"
});
O, más simplemente usando las funciones de flecha de ES6 :
callbackReceiver(value => callback(value, "Foo Bar")); // "Hello World", "Foo Bar"
En cuanto a su ejemplo específico, no he usado la función .post
en jQuery, pero un análisis rápido de la documentación sugiere que la devolución de llamada debe ser un puntero a función con la siguiente firma:
function callBack(data, textStatus, jqXHR) {};
Por eso creo que la solución es la siguiente:
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");
};
¿Que esta pasando?
En la última línea, se invoca doSomething(extraStuff)
y el resultado de esa invocación es un puntero a función .
Debido a que extraStuff
se pasa como un argumento para hacer algo, está dentro del alcance de la función doSomething
.
Cuando se hace referencia a extraStuff
en la función interna anónima devuelta de doSomething
, se vincula mediante el cierre al argumento extraStuff
la función externa. Esto es cierto incluso después de que doSomething
haya regresado.
No he probado lo anterior, pero he escrito un código muy similar en las últimas 24 horas y funciona como lo describí.
Por supuesto, puede pasar varias variables en lugar de un solo objeto ''extraStuff'' dependiendo de sus preferencias personales / estándares de codificación.
Para mí, y otros novatos que acaban de contactar con Javascript,
Creo que la Closeure Solution
es un poco confuso.
Mientras encontré eso, puedes pasar fácilmente tantos parámetros como quieras a cada devolución de llamada ajax usando jquery.
Aquí hay dos soluciones más fáciles .
El primero, que @zeroasterisk ha mencionado anteriormente, ejemplo:
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 );
...
}
});
});
En segundo lugar, pase datos definidos por el usuario agregándolos al XHR object
que existe en toda la vida útil de la solicitud de respuesta 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 );
...
}
});
});
Como puede ver, estas dos soluciones tienen el inconveniente de que: necesita escribir un poco más de código cada vez que simplemente escribir:
$.get/post (url, data, successHandler);
Lea más sobre $ .ajax: http://api.jquery.com/jquery.ajax/
Puede utilizar un cierre de JavaScript:
function wrapper( var1, var2,....) // put here your variables
{
return function( data, status)
{
//Handle here results of call
}
};
y cuando puedes hacer:
$.post("someurl.php",data,wrapper(var1, var2, etc...),"html");
Si alguien viene aquí, esta es mi opinión:
$(''.selector'').click(myCallbackFunction.bind({var1: ''hello'', var2: ''world''}));
function myCallbackFunction(event) {
var passedArg1 = this.var1,
passedArg2 = this.var2
}
Lo que sucede aquí, después de vincularse a la función de devolución de llamada, estará disponible dentro de la función como this
.
Esta idea proviene de cómo React utiliza la funcionalidad de bind
.
También puedes probar algo como lo siguiente:
function clicked() {
var myDiv = $("#my-div");
$.post("someurl.php",someData,function(data){
doSomething(data, myDiv);
},"json");
}
function doSomething(curData, curDiv) {
}
Una solución más general para enviar solicitudes asíncronas utilizando la API jQuery .ajax()
y los cierres para pasar parámetros adicionales a la función de devolución de llamada:
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);
});
};
en realidad, su código no funciona porque cuando escribe:
$.post("someurl.php",someData,doSomething(data, myDiv),"json");
coloca una llamada de función como tercer parámetro en lugar de una referencia de función .
$(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);
}
Vía secundaria:
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 --
}