#javascript #jquery
#javascript #jquery
Вопрос:
У меня на странице большое количество входов, каждый вход по умолчанию отключен (и скрыт), если не установлен флажок. Установка соответствующего флажка позволяет пользователю вводить сумму — это работает нормально.
После того, как я ввел сумму в заданное поле и переключил фокус размытия на что-то другое (указывая, что я закончил с этим вводом), я просматриваю каждый видимый ввод, чтобы проверить, есть ли в нем сумма, а затем отправляю ajax-запрос для обновления серверной части (это тоже работает, но, возможно, подход неправильный?).
Что не работает, так это то, что когда я перебираю более 5-10 флажков, это кажется чрезвычайно медленным или просто не отправляет ajax-запросы.
Запрограммируйте прослушивание для изменения поля включенной / видимой суммы:
$(document).on("blur", ".dollar-amount", function(){
MainPage.amountInputListener('add');
});
Вот цикл foreach, который обновляет внутренние данные каждого связанного пользователя с количеством в видимом поле:
var MainPage = {
amountInputListener: function (type) {
$(".dollar-amount:visible").each(function () {
//Get the employee being updated
var empID = $(this).data('empid');
//get the amount
var amount = $(this).val();
//Send update request to backend
$.ajax({
type: "POST",
url: "update/amount?empid=" empID "amp;amt=" amount 'amp;type=' type,
dataType: "html"
});
});
},
}
HTML для ввода:
<input type="text" name="dollar_hour_amountX" value="0" class="form-control dollar-amount disabled" data-empid="1" tabindex="-1" disabled>
Примечание: dollar_hour_amountX
X — это динамическое число, связанное с идентификатором сотрудника строки. data-empid
это то же динамическое число, также используемое в цикле for.
Что я пытался сделать, чтобы цикл работал должным образом:
-
Добавление
async: false
. Это позволяет ему работать в 100% случаев, но при добавлении большего количества входных данных он становится чрезвычайно медленным. -
Добавление тайм-аута в 100-1000 мс для всей функции, это просто задерживает время выполнения Ajax-вызова в оба конца.
Я открыт для предложений ванильного JS, если это поможет сделать вызовы моего серверного модуля намного быстрее и последовательнее.
Комментарии:
1. Зачем отправлять все данные в blur? Почему бы просто не отправить данные для того, который был только что размыт, предполагая, что это тот, который изменился
2. Это то, что я считаю лучшим, и моя конечная цель, но я не нашел способа отправлять только недавно размытые данные элемента.
3.
e.target
в вашем обработчике событий делегата размытия элемент будет размытым, при условии, что вы передаетеe
в прослушиватель. Передайте это в свой метод и используйте его4. Таплар прав, никогда не выполняйте ajax-запросы в цикле, либо вы отправляете все данные в одном запросе, либо отправляете только те данные, которые фактически были изменены.
5. Очень признателен за понимание и советы. Я собираюсь внести некоторые коррективы и изменить свой подход. Я знаю, что отправка такого количества Ajax-запросов — это большой запрет, просто нужно было немного присмотреться.
Ответ №1:
// capture the passed in event
$(document).on("blur", ".dollar-amount", function(e){
// give the element to the method
MainPage.amountInputListener(e.target, 'add');
});
var MainPage = {
// accept the element on the arguments
amountInputListener: function (element, type) {
// use the element in place of `this`
//Get the employee being updated
var empID = $(element).data('empid');
//get the amount
var amount = $(element).val();
//Send update request to backend
$.ajax({
type: "POST",
url: "update/amount?empid=" empID "amp;amt=" amount 'amp;type=' type,
dataType: "html"
});
},
}
Комментарии:
1. Я знаю, что люди могут сослаться на «отсутствие объяснения того, что это делает». Но ваши комментарии в другом месте помогли мне, и этот пример кода был тем, с чем я закончил, и помог все сгладить. Я ценю это.
Ответ №2:
Не имеет смысла обновлять все, просто обновите то, что меняется.
$('.dollar-amount').on("change", function () {
console.log(this.value, $(this).data('empid'))
// make the one Ajax request
})
Или измените свой серверный интерфейс, чтобы иметь возможность обрабатывать несколько отправляемых данных одновременно, чтобы вы не забивали серверную часть кучей вызовов.
Ответ №3:
«Я просматриваю каждый видимый ввод, чтобы проверить, есть ли в нем значение, а затем отправляю ajax-запрос для обновления серверной части (это тоже работает, но, возможно, подход неправильный?)».
Я бы настоятельно рекомендовал вам изменить этот подход. Я подозреваю, что это исправит ваши проблемы. Не перебирайте все это каждый раз. В этом нет необходимости. Просто, при размытии, просто проверьте, изменился ли этот конкретный ввод, а затем отправьте вызов ajax, ТОЛЬКО если этот конкретный ввод был отредактирован.
Просто передайте «this» в amountInputListener в качестве аргумента, а затем избавьтесь от вышеупомянутой функции «each». Остальное было бы таким же. Вместо $(this) просто передайте значение аргумента, которое представляет «это» из события.
Ответ №4:
Первое и главное — следует избегать использования запроса get http verb для обновления. Это не соответствует стандарту, обычно запросы get используются для извлечения данных.
И следующее, что нужно сделать, это вместо вызова ajax для каждого элемента с callname .в долларовом эквиваленте и для видимости лучше объявить глобальную переменную над блоком foreach типа array объектов, а затем добавить каждый элемент в блоке в эту глобальную переменную, а затем, наконец, выполнить ajax-запрос после завершения выполнения блока for
amountInputListener: function (type) {
var objList = [];
$(".dollar-amount:visible").each(function () {
//Get the employee being updated
var empID = $(this).data('empid');
//get the amount
var amount = $(this).val();
//Send update request to backend
objList.push({
'empId':empId,
'amt':amount,
'type': type
});
});
$.ajax({
type: "post",
url: "update/amount"
dataType: "application/json",
data:{'data':objList}
});
},
}
Таким образом, вы можете отправить все данные за один раз на сервер, и это действительно повышает производительность.
Примечание: код предназначен только для того, чтобы дать вам представление.