var smth = new Array("1","2","3");
for(var i=0;i<smth.length;i++){
    $("#id"+i+"_del").click(function(){
            $.ajax({
                type: 'POST',
                url: 'delete.php',
                data: {filek : smth[i]},
                success: function(html){
                    console.log(html);
                }
            });
    });
};

¿Cómo enviar "smth [i]" por datos en ajax? Cuando hago var antes de ajax, siempre es el último y todos los botones envían el último elemento de la matriz.

1
KanekiSenpai 28 oct. 2017 a las 02:58

4 respuestas

La mejor respuesta

Para evitar jugar con bucles indexados, puede probar el enfoque de expresiones regulares, algo como esto:

$('div')
  .filter(function() {
    return this.id.match(/^id\d+_del$/);
  })
  .click(function() {
    let id = this.id.match(/id(\d+)_del/)[1];

    $.ajax({
      type: 'POST',
      url: 'delete.php',
      data: { filek: smth[id] },
      success: function(html) {
        console.log(html);
      },
    });
  });

JSFiddle (consulte la pestaña de la red para ver los XHR)

Básicamente, toma todos los divs con identificadores que comienzan con id, que tienen algún número en el medio y terminan con _del, luego vincula una llamada ajax a cada uno utilizando el número capturado de la identificación. En mi opinión, esto es mucho más limpio, aunque aún debe asegurarse de que smth tenga todos los elementos que necesita.

Dicho esto, como otros mencionaron, sugeriría usar clases y atributos de datos en los divs, que pueden aprovechar soluciones más seguras e inteligentes sin trucos como este.

Editar:

Enfoque de clase / datos:

$('.del').click(function() {
  let id = $(this).data('filek-id');

  console.log(`Id: ${id}`);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="del" data-filek-id="0">Foo click me</div>
<div class="del" data-filek-id="1">Bar click me</div>
<div class="del" data-filek-id="2">Baz click me</div>
0
Pedro Fialho 28 oct. 2017 a las 13:47

El controlador puede obtener la ID del elemento de destino y extraer i de eso:

var smth = new Array("1","2","3");
for(var i=0;i<smth.length;i++){
    $("#id"+i+"_del").click(function(){
        var i = parseInt(this.id.substr(2), 10);
        $.ajax({
            type: 'POST',
            url: 'delete.php',
            data: {filek : smth[i]},
            success: function(html){
                console.log(html);
            }
        });
    });
};

Aquí se pueden encontrar otras soluciones más generales al problema de las variables de iteración y los cierres: JavaScript cierre dentro de bucles - ejemplo práctico simple

0
Barmar 28 oct. 2017 a las 00:22

No use un bucle for para eso y no use identificadores numerados. Pero si TIENE que usar identificadores numerados y no puede agregar una clase CSS: simplemente verifique el principio y el final para que no necesite el bucle:

var smth = ["1","2","3"];
$("[id^=id][id$=_del]").click(function(){
    let i = parseInt(this.id.substr(2), 10);
    $.ajax({
        type: 'POST',
        url: 'delete.php',
        data: {filek : smth[i]},
        success: function(html){
            console.log(html);
        }
    });
};
0
Joshua K 28 oct. 2017 a las 00:14

La pregunta en OP se discutió en TAN muchas y muchas veces. El nombre del problema es Ejecución de función asíncrona en el bucle .

Primero mira lo que está mal con OP:

var smth = new Array("1","2","3");
for(var i=0;i<smth.length;i++){
    $("#id"+i+"_del").click(function(){// i comes from the loop and is OK
        $.ajax({
            type: 'POST',
            url: 'delete.php',
            data: {filek : smth[i]},//the code runs *after* the loop is completed and **i** is 3 (in this case)
            success: function(html){
                console.log(html);
            }
        });
    });
};

¿Cómo solucionarlo?
Si ES6 está disponible, entonces no hay problema. Leer documentación

for(let i=0;i<smth.length;i++){// i is scoped to the loop
//  ^^^
// OP code
}

De lo contrario, un cierre es la solución

var smth = new Array("1","2","3");
for(var i=0;i<smth.length;i++){
   (function(j){ // it is possible to use **i** but it will be different **i**
     $("#id"+j+"_del").click(function(){// 
          $.ajax({
            type: 'POST',
            url: 'delete.php',
            data: {filek : smth[j]},// j keeps the value
            success: function(html){
                console.log(html);
            }
        });

    });})(i);
};
0
Alex Kudryashev 28 oct. 2017 a las 01:25