2010-06-11 10 views
9

En el siguiente ejemplo de código, la función de devolución exitosa registra 'entrada # 04.update' cuatro veces en lugar de cada entrada individual, lo cual tiene sentido para ver cómo funcionan los cierres, pero ¿cómo haré para cada uno? entrada individual usando esto.AJAX Cierres y segmentación 'esto'

<input type="text" name="" id="01" class="update"> 
<input type="text" name="" id="02" class="update"> 
<input type="text" name="" id="03" class="update"> 
<input type="text" name="" id="04" class="update"> 

function updateFields(){ 
$('input.update').each(function(){ 
    $this = $(this); 
    $.ajax({ 
     data: 'id=' + this.id, 
     success: function(resp){ 
     console.log($this); 
      $this.val(resp) 
     } 
    }); 
    }); 
} 

Respuesta

12

se le olvidó var

var $this = $(this); 

No se olvide var. Un programador que olvidó var se fue a la cama por la noche y se despertó para encontrar su apartamento en llamas. Añadió var y el fuego se apagó. Otro programador dejó var fuera de completamente poco antes de partir en un viaje de negocios a Europa. El avión desarrolló problemas mecánicos en vuelo poco después del despegue, lo que provocó que el piloto iniciara procedimientos de aterrizaje de emergencia. Desde su computadora portátil, el programador agregó rápidamente var y el avión lo hizo de manera segura a un aeropuerto.

No se olvide var. Si coloca var en su código, conocerá a alguien especial hoy. Intentalo. ¡Parece increíble, pero realmente funciona!

+0

Eso es increíble ... pero ... ¿podría decirme una razón técnica para hacer eso? Quiero decir, a veces me olvido de agregar 'var' ... y no he tenido problemas. Pero tus palabras son aterradoras, y de ahora en adelante no me olvidaré de agregar 'var'. De todos modos ... ¿tienes una explicación técnica para este tipo de problemas? – Cristian

+0

El motivo: su controlador 'success', función anónima hace referencia a una variable' $ this' que es global. Entonces, cada una de las 4 instancias de esta función anónima hace referencia a la misma variable y, por lo tanto, al mismo valor, ya que se ejecutan mucho después de que la función 'each' haya regresado. – Alsciende

+1

@Cristian: sin la 'var', es una variable global que está actualizando cada bucle, no local para el alcance de este cierre, en este caso lo quiere que sea. –

3

de correcto en var uso puntiagudo, otra alternativa es utilizar $.proxy(), así:

function updateFields(){ 
$('input.update').each(function(){ 
    $.ajax({ 
     data: 'id=' + this.id, 
     success: $.proxy(function(resp){ 
       $(this).val(resp); 
       }, this) 
    }); 
    }); 
} 

Este creador de cierre hará this referirse al elemento de entrada cuando se está dentro de la success de devolución de llamada, que es por lo general lo que está buscando ... así que no estoy seguro de por qué este no es el caso por defecto, pero en cualquier caso $.proxy() rectifica la situación.

+0

+1 por hacerme leer en '$ .proxy()'. – user113716

+0

'$ .proxy()' es bueno, pero me gustaría que también admitiera el "relleno de parámetros" o el currículum falso que admite el '.bind' de Prototype. Ahora tendré que verificar si el nuevo ECMAScript 5 '.bind' es como el de Prototype. – Pointy

+0

@Pointy - El segundo enfoque '$ .proxy()' puede hacer una mutación como esta dependiendo de cómo la estructure ... pero sí, no está a la altura del prototipo, pero creo que en realidad no falta mucho ... Creo que las 2 bibliotecas solo adoptan un enfoque muy diferente al enlace y la iteración con respecto a los cierres, jQuery tiende a crear más para usted en el camino, para bien o para mal. –