AddEventListener только удаляет последнюю стоимость цикла с кнопками

Я ищу способ использовать addEventListener, и что произвел желанную стоимость, посланную моим fuction (стоимость). Только возьми последнюю стоимость цикла.

 function deleteItem(index){

                cart.splice(index,1);
                showCart();
                saveCart();

            }




         function mostrar_carrito() {


                    $("#cart").css("visibility", "visible");
                    $("#cartBody").empty();

                    for (var i in cart) {

                        var item = cart[i];
                        var row = "<tr><td>" + item.Product + "</td><td>" +
                                     item.Price + "</td><td>" + item.Qty + "</td><td>"
                                     + item.Qty * item.Price + "</td><td id='someArea'>"



            var button = document.createElement("button");
            button.innerHTML = i;
             button.addEventListener("click", function(){ deleteItem(i); });
             + "</td></tr>"


                        $("#someArea").append(button);
                        $("#cartBody").append(row);


                    }
                }

Большое спасибо.

3
задан 23.08.2016, 23:41
2 ответа

Это проблема (в действительности это feature) хорошо известно как "Clousure внутри loop". и встречается, когда ты объявляешь функцию внутри loop.

Есть несколько способов это решать. Самая простая состоит в том, чтобы использовать let вместо var. Тема - что переменные, объявленные с var они глобальные в функцию и ввиду этого все handlers заканчивают тем, что указывают в ту же стоимость (как будто об указателях он относился друг к другу), а именно, на который все кнопки указывают в последнюю стоимость, которая взяла переменную i. Но let различная опера и каждое повторение цикла использует различную инстанцию переменной.

пример:

for(let i in cart) { 
  // .. restro del codigo
}

Но если тебе будет нужно, чтобы оно функционировало в браузерах Legacy, этот выбор не будет служить, так как она была добавлена недавно в ES2015.

В этом случае ты был бы должен использовать внешнюю функцию, чтобы менять scope переменной i.

что-то подобное

for(var i in cart) { 
  otrafuncion(i);
}

// luego fuera del loop, creas la función otraFuncion con el código que ya tenias. 
function otraFuncion(i) {
  // restro del codigo aqui.
} 

привет.

РЕДАКТИРОВАНИЕ:

Тот же пример, который воспроизводит проблему, которая у тебя есть (упорядоченная часть #someArea):

$(function() {
  var cart = [{
    id: 1,
    Product: "Papa negra",
    Qty: 10,
    Price: 10.3
  }, {
    id: 2,
    Product: "Papa blanca",
    Qty: 5,
    Price: 15.9
  },{
    id: 3,
    Product: "Papa falsa",
    Qty: 5,
    Price: 3.9
  }];

  function deleteItem(index) {
    alert(index);
    //cart.splice(index, 1);
    //mostrar_carrito();
  }

  function mostrar_carrito() {
    $("#cart").css("visibility", "visible");
    $("#cartBody").empty();

    for (var i in cart) {
      var item = cart[i];
      var row = "<tr><td>" + item.Product + "</td><td>" +
        item.Price + "</td><td>" + item.Qty + "</td><td>" +
        item.Qty * item.Price + "</td><td id='item" + item.id + "'/>";

      $("#cartBody").append(row);

      var button = document.createElement("button");
      button.innerHTML = "borrar";
      button.addEventListener("click", function() {
        deleteItem(i);
      });

      $("#item" + item.id).append(button);


    }
  }
  
  mostrar_carrito();
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cart">
  <table id="cartBody">
  </table>
</div>

и Решение, используя способ извлекать функцию:

$(function() {
  var cart = [{
    id: 1,
    Product: "Papa negra",
    Qty: 10,
    Price: 10.3
  }, {
    id: 2,
    Product: "Papa blanca",
    Qty: 5,
    Price: 15.9
  }, {
    id: 3,
    Product: "Papa falsa",
    Qty: 5,
    Price: 3.9
  }];

  function deleteItem(index) {
    alert(index);
    //cart.splice(index, 1);
    //mostrar_carrito();
  }

  function mostrar_carrito() {
    $("#cart").css("visibility", "visible");
    $("#cartBody").empty();

    for (var i in cart) {
      creaRegistro(cart[i], i);      
    }
    
    function creaRegistro(item, index) {
	      var row = "<tr><td>" + item.Product + "</td><td>" +
		item.Price + "</td><td>" + item.Qty + "</td><td>" +
		item.Qty * item.Price + "</td><td id='item" + item.id + "'/>";

	      $("#cartBody").append(row);

	      var button = document.createElement("button");
	      button.innerHTML = "borrar";
	      button.addEventListener("click", function() {
		deleteItem(index);
	      });

	      $("#item" + item.id).append(button);
    }

  }

  mostrar_carrito();
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cart">
  <table id="cartBody">
  </table>
</div>

Другой пример с let

$(function() {
  var cart = [{
    id: 1,
    Product: "Papa negra",
    Qty: 10,
    Price: 10.3
  }, {
    id: 2,
    Product: "Papa blanca",
    Qty: 5,
    Price: 15.9
  },{
    id: 3,
    Product: "Papa falsa",
    Qty: 5,
    Price: 3.9
  }];

  function deleteItem(index) {
    alert(index);
    //cart.splice(index, 1);
    //mostrar_carrito();
  }

  function mostrar_carrito() {
    $("#cart").css("visibility", "visible");
    $("#cartBody").empty();

    for (let i in cart) {
      var item = cart[i];
      var row = "<tr><td>" + item.Product + "</td><td>" +
        item.Price + "</td><td>" + item.Qty + "</td><td>" +
        item.Qty * item.Price + "</td><td id='item" + item.id + "'/>";

      $("#cartBody").append(row);

      var button = document.createElement("button");
      button.innerHTML = "borrar";
      button.addEventListener("click", function() {
        deleteItem(i);
      });

      $("#item" + item.id).append(button);


    }
  }
  
  mostrar_carrito();
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cart">
  <table id="cartBody">
  </table>
</div>
1
ответ дан 24.11.2019, 13:35
  • 1
    Превосходный!!! Конечно он состоял в том, чтобы инициализировать funci и # 243; n, задолго до которого он ждал. Спасибо.:) –  GoIn Su 26.08.2016, 03:36

С кодом, который ты имеешь, я реализовал маленькое доказательство в JSFiddle, что я здесь имею тебе https://jsfiddle.net / jgvxnyae / 1/, возможно смогите бросать взгляд в этот и видеть, - то, ли что ты ищешь это.

Я нашел, что в коде, который ты имеешь, так называемом td someAreaон идет создавать количество раз, которые существовали бы в договоренности, и когда ты добавляешь кнопку к этому контенту jQuery, возвращает первого, что он находит и здесь добавляет кнопку, так что я принял решение изменить этот, пойдите и увеличивать это из-за каждой статьи, которая существует в договоренности.

$("#btnCarrito").on("click", function() {
  mostrar_carrito();
})

function mostrar_carrito() {

  $("#cart").css("visibility", "visible");
  $("#cartBody").empty();

  for (var i in cart) {
    var button = document.createElement("button");
    button.innerHTML = i;
    button.addEventListener("click", function() {
      deleteItem(i);
    });

    var item = cart[i];
    var row = "<tr><td>" + item.Nombre + "</td><td>" + item.Valor + "</td><td>" + item.Cantidad * item.Valor + "</td><td id='someArea" + i + "'></td></tr>"
    
    $("#cartBody").append(row);
    $("#someArea" + i).append(button);
  }
}

function deleteItem(index) {
  alert(index);
}

function objetoVenta(valor, nombre, cantidad) {
  this.Valor = valor;
  this.Nombre = nombre;
  this.Cantidad = cantidad;
}

var camisa = new objetoVenta(1000, "Camisa", 1);
var pantalon = new objetoVenta(2000, "Pantalón", 2);
var cart = [camisa, pantalon];
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="btnCarrito" value="Mostrar Carrito" type="button" />
<table id="cart">
  <tbody id="cartBody">

  </tbody>
</table>

Я надеюсь, что это помогает тебе находить решение, в котором ты нуждаешься.

1
ответ дан 24.11.2019, 13:35
  • 1
    Хороший observaci и # 243; n, не hab и # 237; в прибывший ах и # 237; но у тебя есть raz и # 243; n. Однако то, что я ищу в s и # 237; дело в том, что в момент удаления продукта с ним addEventListener deleteItem (i); пара и # 225; метр, который он посылает, не правильный. Всегда удали и #250; ltimo цикла. –  GoIn Su 25.08.2016, 03:07
  • 2
    @GoInSu всегда удали последний элемент а следовательно я объяснил тебе в моем ответе. В javascript, в отличие от многих других языков, не моги становиться funci и # 243; n в blucle и указывать на переменную цикла без того, чтобы он это переместил. Привет., –  rnrneverdies 25.08.2016, 15:30
  • 3
    Если проблема - то, что упоминает @md тогда о том, что возможно делать, он состоит в том, чтобы захватывать переменную цикла и посылать ее вместо той, которая делает часть цикла. Не, если альтернатива состояла в том, чтобы делать cl и # 243; n объекта, с небольшим количеством м и # 225; s c и # 243; я говорю, чтобы знать м и # 225; s контекст podr и # 237; чтобы давать лучший ответ. –  Fabio Julián Bernal 25.08.2016, 17:35
  • 4
    Проблема, если, он состоит в том, что Chrome extensions не позволяет использование onclick (), а следовательно он используется addEventListener. Если существовала возможность с признаком < a> < / a> чтобы перемещать переменную вероятно я предотвратил все я прокручиваю этот. и #191; Кто-то знает о какой-то форме?, я не встречаю ни одной. Уже пробуйте с posiblidad @rnd, но я не могу делать никакого opci конкретным и # 243; n. –  GoIn Su 26.08.2016, 02:47
  • 5
    @GoInSu есть другие ошибки в твоем коде сейчас, когда он попробовал это выполнить, ты исправил их, автомобиль не строится правильно. Ты можешь acutlaizar в твою последнюю версию и я показываю тебе, как исправлять это? –  rnrneverdies 26.08.2016, 02:56

Теги

Похожие вопросы