Я просто хочу сделать три вещи по порядку.
В моей таблице тысячи строк, и для ее сортировки требуется некоторое время.Я хотел бы, чтобы мой «ожидающий» модал отображался во время сортировки, но страница ожидает завершения сортировки, прежде чем пытаться отобразить модал.
Вот jsfiddle .(Вы можете увеличить или уменьшить bignumber
, чтобы получить задержку сортировки, которую вы можете видеть, но это не раздражает.)
Я впервые попробовал:
//CSS: body.loading .waitingModal {display: block;}
$('body').toggleClass("loading"); // happens second!
sortTable(currentdirection,columnno); // takes ages and happens first
$('body').toggleClass("loading"); // happens third
Если я закомментирую последнюю строкуили вызвать ошибку перед этим, таблица сортируется, затем модальное появляется.
Благодаря этому вопросу моя следующая попытка сработала один раз, но затем модальный режим загрузки больше не появлялся:
$('body').toggleClass("loading");
setTimeout(function() { //loading works but not if you click again
sortTable(order,1);
$('body').toggleClass("loading");
}
Веб-страницы, на которых люди советуют мне использовать jQuery.Deferred
вместо того, чтобы запутаться в аду обратного вызова, и так как я не мог видеть, куда поместить обратный вызов, и ад обратного вызова не кажется забавным, я согласился с этим.
Я читаю вопросы по Какиспользуйте jQuery deferred и , затем vs done и, что наиболее многообещающе, Пример 1 этого ответа из цепочки , но все, кажется, предполагают, что у меня уже есть отложенное / обещание, уже появляющееся из некоторого ajaxили что-то в этом роде.
Моя первая попытка связать некоторые .then(...)
вызовы не сработала, потому что буквально ничего не произошло:
$.Deferred().then(function(){
$('body').toggleClass("loading"); //doesn't happen
}).then(function(){
sortTable(order,1); //doesn't happen
}).then(function(){
$('body').toggleClass("loading"); //doesn't happen
});
При использовании параметра beforeStart
мой модал отображался,но ничего больше:
$.Deferred(function(it){
$('body').toggleClass("loading"); //happens first, hooray!
}).then(function(){
sortTable(order,1); //doesn't happen
}).then(function(){
$('body').toggleClass("loading"); //doesn't happen
});
Затем я попытался связать несколько отсроченных then
s, явно разрешив и передав отложенное, но я явно не понимаю, как это работает:
$.Deferred().then(function(it){
$('body').toggleClass("loading"); //still happens second
it.resolve();
return it.promise();
}).then(function(){
sortTable(order,1); //happens first
}).then(function(){
$('body').toggleClass("loading"); //happens third
});
LaВ действительности, я пытался разрешить deffered
события изменения в теле
function loadingNow(){
var deferred = $.Deferred();
$('body').toggleClass("loading") // happens
.change(function(){
deferred.resolve()
});
return deferred.promise();
}
loadingNow().then(function(){
sortTable(order,1); //doesn't happen
}).then(function(){
$('body').toggleClass("loading"); //doesn't happen
});
Не имеет значения, переключаю ли я класс после добавления обработчика события изменения:
function loadingNow(){
var deferred = $.Deferred();
$('body').change(function(){
deferred.resolve()
}).toggleClass("loading"); // happens
return deferred.promise();
}
loadingNow().then(function(){
sortTable(order,1); //doesn't happen
}).then(function(){
$('body').toggleClass("loading"); //doesn't happen
});
Честно говоря, я не ожидал, что будет настолько сложно убедить jQuery сделать три вещи по порядку.Возможно, есть намного более простая вещь, о которой я не думал.Я не возражаю, если обратные вызовы или Deferred
сделаны правильно, но если они краткие и относительно ясные, это будет огромным бонусом.