Mantener un valor consistente en jQuery en la función cuando se ejecuta en varios elementos al mismo tiempo

Estoy escribiendo un módulo que tiene múltiples preguntas que los usuarios pueden elegir responder. Cada uno tiene su propio botón de envío que hace que los datos se publiquen en mi solicitud, muestra los resultados y luego elimina el formulario. Pude hacer que esta pieza funcionara perfectamente, pero si agrego un botón que permite a los usuarios enviar todos los formularios a la vez, envía los datos del formulario correctamente, pero los resultados se agregan a la última pregunta (los elementos obtienen los datos correctos) . Este es el código javascript/jQuery que estoy usando:

// setup the save answer click handler
$(document).on('click', '.saveAnswer', function(event){
    event.preventDefault();

    // get the form
    form = $(this).closest('form');

    $.ajax({
        async:true,
        type: 'POST',
        url: form.attr('action'),
        data: form.serialize(),
        success: function(data){
            // append the text to the bottom of the answers
            form.closest('.question').find('.answers').append('<li>' + data + '</li>').hide().slideDown(500);

            form.slideUp(500,function(){
                form.remove();
            });
        }
    });

});

// setup the save all answer click handler
$(document).on('click', '.saveAll', function(){
    $('.saveAnswer').trigger('click');
});

Si cambio el async valor a falso, entonces funciona correctamente, pero ninguna de las animaciones funciona y la página parece congelarse por un segundo hasta que se envían todas las respuestas.

Después de un poco de depuración, descubrí que el form la variable se sobrescribe cada vez que se ejecuta la función. ¿Hay alguna manera de evitar que esto suceda?

preguntado el 22 de mayo de 12 a las 16:05

form es una variable global (o al menos de mayor alcance). Hazlo local (var form = $(....);). -

@DCoder Gracias por la rápida respuesta. Agregue eso como respuesta y lo aceptaré. -

2 Respuestas

form es una variable global (o al menos de mayor alcance), lo que significa que cada llamada al controlador pisotea el valor anterior, y el success/error todas las devoluciones de llamada comparten el mismo valor.

Hazlo local (var form = $(....);), de modo que cada invocación del controlador tenga su propio valor.

contestado el 22 de mayo de 12 a las 16:05

En caso de que no desee cambiar el alcance de la variable, puede usar el cierre para almacenar una variable de formulario como esta

form = $(this).closest('form');
$.ajax({
        .....
        success:(function (formClosure) {
            return function(data){ 
            // for this function formClosure will be local variable, 
            // so changing form variable doesn't take effect
            formClosure.closest('.question').find('.answers').append('<li>' + data + '</li>').hide().slideDown(500);

            formClosure.slideUp(500,function(){
                form.remove();
            });
          };
        })(form)
    });

contestado el 22 de mayo de 12 a las 16:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.