jQuery .change с .each внутри не срабатывает должным образом

У меня есть простая функция .change, которая обращается к базе данных и получает некоторые значения, устанавливает некоторые значения и т. д.

$('.linequantity').change(function() {
    ...
    $.getJSON(url, function(data) {
      $('#TT-' + lineItem).text(parseFloat(data['price']) * quantity);
    });
});

Тогда я хочу, чтобы в любой из строк менялись количественные показатели, я хочу обновить промежуточный итог. (Да, это приложение в стиле каталога/корзины для покупок). Я подумал, давайте использовать .each

$('.linequantity').each(function(){
     ...
   var url = "jQueryFunctions.php?action=getPrice&quantity=" + quantity + "&customer=" + customerID + "&item=" + lineItem;

    $.getJSON(url, function(data) {
       subtotal = subtotal + (parseFloat(data['price']) * quantity);
     });
   });

   $('#subtotal').text(subtotal);

когда я это делаю, я получаю 0 для промежуточного итога, если каждый из них вообще срабатывает.

Я устал помещать .each в функцию. Когда я переместил .each в его собственную функцию, он сработал более последовательно, но getJSON, который в .change отлично работает, пропускается.

Я сталкиваюсь с конфликтом первого запроса json, который не совсем завершен, прежде чем я попрошу еще один?

Я открыт для изменения методологии, но вышеизложенное имеет правильную идею/начало.

Любые идеи?

EDITS
поле количества

<input type="text" class="linequantity" id="SQ-<?php echo $value['itemNumber']; ?>" name="Quantity" placeholder="#"/>

общий пролет

<span id="subtotal" class="currencyField">$0.00</span>

11:44 РЕДАКТИРОВАТЬ: я думаю, что .each срабатывает до завершения getJson. Как я могу убедиться, что запрос json выполнен до того, как я не сделаю jQuery


person Kris.Mitchell    schedule 31.05.2012    source источник
comment
Какие элементы HTML имеют класс linequantity? Вы можете включить свой HTML?   -  person Manse    schedule 31.05.2012
comment
Вы можете создать action для getSubtotal, чтобы вам не приходилось делать это в цикле.   -  person Explosion Pills    schedule 31.05.2012
comment
@ExplosionPills, возможно, мне промыли мозги jQuery, но что вы подразумеваете под действием?   -  person Kris.Mitchell    schedule 31.05.2012
comment
@ManseUK — обновлено несколько html для поддержки   -  person Kris.Mitchell    schedule 31.05.2012
comment
Ваша собственная терминология (jQueryFunctions.php?*action*=getSubtotal...)   -  person Explosion Pills    schedule 31.05.2012
comment
@ExplosionPills Я думал об этом, имея где-то промежуточную сумму в базе данных, но пока они не пойдут и не разместят заказ, я не хотел, чтобы где-то находились какие-либо строки в таблице.   -  person Kris.Mitchell    schedule 31.05.2012


Ответы (2)


Я думаю, что у вас просто состояние гонки, из-за которого запросы ajax выполняются слишком поздно. Единственный способ обойти это — иметь методы, которые зависят от запросов, запускаемых после их завершения. Есть много способов сделать это, например, используя Deferred и $.when. Простой способ был бы хорош:

$.getJSON(...)
   .done(function () {
      // Stuff that depends on JSON goes here
   });

В .each вы зависите от нескольких запросов - возможно, много за раз. Я бы попытался сделать это в одном запросе (например, обновить код вашего сервера, чтобы принять список элементов и вычислить промежуточный итог, а не просто иметь их по одному). В противном случае вам придется постоянно обновлять промежуточный итог, что может привести к его визуальному мерцанию. Это также неэффективно для сервера. Вы можете сделать что-то вроде:

var jqXHRs = []
$.each(...
   jqXHRs.append($.getJSON(...));
);
$.when(jqXHRs).done(...);

... но я не уверен, будет ли $.when работать с таким массивом или есть ли способ расширить список аргументов до него.

person Explosion Pills    schedule 31.05.2012
comment
В итоге я пошел совершенно другим путем с этой проблемой, но много читал о событиях jQuery. .done — это ключ к тому, чтобы убедиться, что событие завершено, прежде чем переходить к следующему. Я согласился, потому что ты начал меня с пути. Спасибо за помощь. - person Kris.Mitchell; 19.06.2012

.change() следует использовать только для элементов, блоков и элементов.

Имея это в виду, вам, вероятно, нужно сделать вызов $().val(); чтобы получить активный пользовательский выбор / входные данные.

что-то вроде этого может сделать это:

$('.linequantity').change(function() {
    var inputData = $(this).val();
    // other stuff!
});
person busticated    schedule 31.05.2012
comment
.change находится над полями ввода. ... выше getJSON - это вызовы .val для получения разных вещей на странице html. - person Kris.Mitchell; 31.05.2012