2010-07-21 16 views
64

Tengo un pequeño problema con la función jquery $ .ajax().jquery - valor devuelto usando el resultado ajax en caso de éxito

Tengo un formulario donde cada clic en el botón de opción o selección en el menú desplegable crea una variable de sesión con el valor seleccionado.

Ahora - Tengo uno de los menús desplegables que tienen 4 opciones - el primero (con la etiqueta Ninguno) tiene un valor = "" otros tienen sus identificadores.

Lo que quiero que suceda es una opción Ninguno (con valor en blanco) para eliminar la sesión y otra para crear una, pero solo si la sesión con este nombre de selección específico no existe ya que todas las demás opciones tienen el mismo cantidad asignada, solo indica cuál fue seleccionada.

no estoy seguro si eso tiene sentido - pero tienen un vistazo al código - tal vez esto hará que sea más claro:

$("#add_ons select").change(function() { 
     // get current price of the addons 
     var order_price_addon = $(".order_price_addon").text(); 
     // get price of the clicked radio button from the rel attribute 
     var add = $(this).children('option').attr('label'); 
     var name = $(this).attr('name'); 
     var val = $(this).val(); 


     if(val == "") { 
      var price = parseInt(order_price_addon) - parseInt(add); 
      removeSession(name); 
     } else { 
      if(isSession(name) == 0) { 
       var price = parseInt(order_price_addon) + parseInt(add); 
      } 
      setSession(name, val);    
     } 

     $(".order_price_addon").html(price);  
     setSession('order_price_addon', price);   
     updateTotal(); 
}); 

así - en primer lugar cuando el menú de selección de #add_ons desencadena "cambio "obtenemos algunos valores de algunos elementos para los cálculos.

obtenemos el atributo de etiqueta de la opción de nuestra selección que almacena el valor que se agregará al total, nombre del seleccionado para crear una sesión con este nombre y valor para verificar posteriormente cuál fue seleccionado.

ahora - comprobamos si el valor == "" (que indicaría que la opción Ninguno ha sido seleccionada) y deducimos el monto del total, así como también eliminamos la sesión con el nombre del selecto.

Después de esto es donde comienza el problema - declaración de más.

O sí - queremos comprobar si la función isSession() con el nombre de nuestro selector devuelve 0 o 1 - si devuelve 0, agregamos al total el valor almacenado en el atributo de etiqueta, pero si devuelve 1 - eso sugeriría que la sesión ya existe - entonces solo cambiamos el valor de esta sesión recreándola - pero la cantidad no se agrega.

función

Ahora isSession se ve así:

function isSession(selector) { 
    $.ajax({ 
     type: "POST", 
     url: '/order.html', 
     data: ({ issession : 1, selector: selector }), 
     dataType: "html", 
     success: function(data) { 
      return data; 
     }, 
     error: function() { 
      alert('Error occured'); 
     } 
    }); 
} 

ahora - el problema es - que no sé si el uso de "retorno" devolverá el resultado de la función - ya que no parece trabajo, sin embargo, si pongo los "datos" en la sección de éxito en la alerta, parece devolver el valor correcto.

¿Alguien sabe cómo devolver el valor de la función y luego compararlo en la siguiente declaración?


Gracias chicos - Lo he intentado de la siguiente manera:

function isSession(selector) { 
    $.ajax({ 
     type: "POST", 
     url: '/order.html', 
     data: ({ issession : 1, selector: selector }), 
     dataType: "html", 
     success: function(data) { 
      updateResult(data); 
     }, 
     error: function() { 
      alert('Error occured'); 
     } 
    }); 
} 

entonces la función updateResult():

función updateResult (datos) { resultado = datos; }

resultado - es la variable global - el cual estoy a continuación, tratar de leer:

$("#add_ons select").change(function() { 
     // get current price of the addons 
     var order_price_addon = $(".order_price_addon").text(); 
     // get price of the clicked radio button from the rel attribute 
     var add = $(this).children('option').attr('label'); 
     var name = $(this).attr('name'); 
     var val = $(this).val(); 


     if(val == "") { 
      var price = parseInt(order_price_addon) - parseInt(add); 
      removeSession(name); 
     } else { 
      isSession(name); 
      if(result == 0) { 
       var price = parseInt(order_price_addon) + parseInt(add); 
      } 
      setSession(name, val);    
     } 

     $(".order_price_addon").html(price);  
     setSession('order_price_addon', price);   
     updateTotal(); 
    }); 

pero por alguna razón - no funciona - alguna idea?

+0

posible duplicado de [Cómo devolver la respuesta de un AJAX llamar?] (http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – Bergi

+16

'Tengo un pequeño problema con jquery ....' Este es el problema pequeño más largo Alguna vez he visto ...;) – prageeth

Respuesta

86

El problema es que no puede devolver un valor de una llamada asincrónica, como una solicitud AJAX, y espera que funcione.

La razón es que el código que espera la respuesta ya se ha ejecutado para el momento en que se recibe la respuesta.

La solución a este problema es ejecutar el código necesario dentro la devolución de llamada success:. De esta forma, está accediendo al data solo cuando está disponible.

function isSession(selector) { 
    $.ajax({ 
     type: "POST", 
     url: '/order.html', 
     data: ({ issession : 1, selector: selector }), 
     dataType: "html", 
     success: function(data) { 
      // Run the code here that needs 
      // to access the data returned 
      return data; 
     }, 
     error: function() { 
      alert('Error occured'); 
     } 
    }); 
} 

Otra posibilidad (que es efectivamente lo mismo) es llamar a una función de devolución de llamada dentro de su success: que pasa los datos cuando está disponible.

function isSession(selector) { 
    $.ajax({ 
     type: "POST", 
     url: '/order.html', 
     data: ({ issession : 1, selector: selector }), 
     dataType: "html", 
     success: function(data) { 
       // Call this function on success 
      someFunction(data); 
      return data; 
     }, 
     error: function() { 
      alert('Error occured'); 
     } 
    }); 
} 

function someFunction(data) { 
    // Do something with your data 
} 
+7

PUEDE devolver un valor de una solicitud AJAX, pero eso es solo si lo haces * no asincrónico * (establece la opción 'async: false'). En algunos casos, tener una llamada asincrónica no es un requisito. Más sobre jquery.ajax() doc http://api.jquery.com/jQuery.ajax/, no que 'A partir de jQuery 1.8, el uso de async: falso con jqXHR ($ .Deferred) está obsoleto;' –

+31

" Non-asynchronous "por supuesto, también se puede denominar como" sincrónico ";) –

+0

en los dos métodos sugeridos; es decir. ejecuta la función con éxito, luego tienes que escribir múltiples ajax para diferentes escenarios. esto no ayudará a crear un motor global de envoltura ajax. – wpcoder

26

Hay muchas formas de obtener la respuesta jQuery ajax. Estoy compartiendo con ustedes dos approch común:

Primero:

uso asíncrono = false y dentro de la función de retorno ajax-objeto y posteriormente obtener la respuesta ajax-object.responseText

/** 
* jQuery ajax method with async = false, to return response 
* @param {mix} selector - your selector 
* @return {mix}   - your ajax response/error 
*/ 
function isSession(selector) { 
    return $.ajax({ 
     type: "POST", 
     url: '/order.html', 
     data: { 
      issession: 1, 
      selector: selector 
     }, 
     dataType: "html", 
     async: !1, 
     error: function() { 
      alert("Error occured") 
     } 
    }); 
} 
// global param 
var selector = !0; 
// get return ajax object 
var ajaxObj = isSession(selector); 
// store ajax response in var 
var ajaxResponse = ajaxObj.responseText; 
// check ajax response 
console.log(ajaxResponse); 
// your ajax callback function for success 
ajaxObj.success(function(response) { 
    alert(response); 
}); 

Segundo:

uso $ .extend método y crea una nueva función como ajax

/** 
* xResponse function 
* 
* xResponse method is made to return jQuery ajax response 
* 
* @param {string} url [your url or file] 
* @param {object} your ajax param 
* @return {mix}  [ajax response] 
*/ 
$.extend({ 
    xResponse: function(url, data) { 
     // local var 
     var theResponse = null; 
     // jQuery ajax 
     $.ajax({ 
      url: url, 
      type: 'POST', 
      data: data, 
      dataType: "html", 
      async: false, 
      success: function(respText) { 
       theResponse = respText; 
      } 
     }); 
     // Return the response text 
     return theResponse; 
    } 
}); 

// set ajax response in var 
var xData = $.xResponse('temp.html', {issession: 1,selector: true}); 

// see response in console 
console.log(xData); 

puede hacer que sea tan grande como usted quiere ...

+0

Buena idea, pero 'ajaxObj ['responseText']' no existe cuando se define 'var ajaxResponse' – mu3

+0

¡Perfecto! su primera solución me salvó –

+0

segundo método es 100% ¡OK! ;) –

2

Esto es bastante antiguo y feo, no hagas esto. Debe usar devoluciones de llamada: https://stackoverflow.com/a/5316755/591257
Tenía el mismo problema, lo resolvió de esta manera, usando una var. No estoy seguro si es el mejor pero seguramente funciona. En caso de error, obtiene una cadena vacía (myVar = ''), por lo que puede manejarlo según sea necesario.

var myVar = ''; 
function isSession(selector) { 
    $.ajax({ 
    'type': 'POST', 
    'url': '/order.html', 
    'data': { 
     'issession': 1, 
     'selector': selector 
    }, 
    'dataType': 'html', 
    'success': function(data) { 
     myVar = data; 
    }, 
    'error': function() { 
     alert('Error occured'); 
    } 
    }); 
    return myVar; 
} 
+2

también necesita agregar 'async: false' aquí, porque en modo asíncrono no se garantiza que' data' se guarde en 'myVar' antes de que devuelva' myVar'. –

1
// Common ajax caller 
function AjaxCall(url,successfunction){ 
    var targetUrl=url; 
    $.ajax({ 
    'url': targetUrl, 
    'type': 'GET', 
    'dataType': 'json', 
    'success': successfunction, 
    'error': function() { 
     alert("error"); 
    } 
    }); 
} 

// Calling Ajax 
$(document).ready(function() { 
    AjaxCall("productData.txt",ajaxSuccessFunction); 
}); 

// Function details of success function 
function ajaxSuccessFunction(d){ 
    alert(d.Pioneer.Product[0].category); 
} 

puede ayudar, crear una función llamada ajax común y adjuntar una función que invocar cuando el éxito de la llamada AJAX, véase el ejemplo

3

Añadir async: false a su lista de atributos. Esto fuerza al hilo de JavaScript a esperar hasta que se recupere el valor de retorno antes de continuar. Obviamente, no querría hacer esto en todas las circunstancias, pero si se necesita un valor antes de continuar, esto lo hará.

+2

Nunca debes establecer 'async: false'. Esto bloquea todo en la página durante la recuperación. Ya sabes lo que significa A en AJAX: Asíncrono. La respuesta correcta sería que OP necesita usar la devolución de llamada 'success()' correctamente. – nietonfir

+2

Reconocí el hecho de que todo tiene que esperar. En determinadas circunstancias, la función de llamada puede necesitar un valor devuelto, como agregar un nuevo registro y necesitar una identificación de registro devuelta. Una vez que conoces las reglas, sabes cuándo se pueden romper. Nunca digas nunca. Aquí hay alguien más que está de acuerdo. (http://stackoverflow.com/questions/3880361/returnning-the-response-from-an-jquery-ajax-call) – Hoodlum

+0

Haciéndolo mal allí también, el problema descrito podría resolverse fácilmente de una manera asincrónica. No gana nada haciendo llamadas sincrónicas, por el contrario. – nietonfir

0

Hola tratar asíncrono: falsa en su llamada AJAX ..

+0

obsoleto desde jquery 1.8 como lo señaló @mikewee. – wpcoder

4

vi las respuestas aquí y, aunque útiles, no eran exactamente lo que quería ya que tuve que alterar una gran parte de mi código.

Lo que funcionó para mí, estaba haciendo algo como esto:

function isSession(selector) { 
    //line added for the var that will have the result 
    var result = false; 
    $.ajax({ 
     type: "POST", 
     url: '/order.html', 
     data: ({ issession : 1, selector: selector }), 
     dataType: "html", 
     //line added to get ajax response in sync 
     async: false, 
     success: function(data) { 
      //line added to save ajax response in var result 
      result = data; 
     }, 
     error: function() { 
      alert('Error occured'); 
     } 
    }); 
    //line added to return ajax response 
    return result; 
} 

Esperanza ayuda a alguien

Anakin

+2

En realidad, solo desactivas la sincronización –

Cuestiones relacionadas