Показать диалог ожидания на синхронном AJAX
Я хочу показать диалоговое окно ожидания, пока выполняется синхронный AJAX. Я использую Smart Wizard, чтобы перейти от первого шага к шагу, мне нужно проверить некоторые данные, чтобы сделать это, я должен сделать 3 вызова ajax один за другим, и пока это сделано, я хочу показать диалоговое окно ожидания. Это то, что я делаю.
if (indexes.fromStep==1) {
res=false;
var validatorResult = validator.checkAll($("#install_modbus_form"))
if (validatorResult) {
$("#modal_loader").modal()
$.ajax({
type: "post",
url: url1,
async: false,
dataType: "json",
data:{
data
},
success: function(response)
{
if (response.success)
{
$.ajax({
type: "post",
url: url2,
async: false,
dataType: "json",
data:{
data
},
success: function(response)
{
if (response.success)
{
$.ajax({
type: "post",
url: url3,
async: false,
dataType: "json",
data:{
data
},
success: function(response)
{
if (response.success)
{
//make magic here
res=true;
}
},
failure:function()
{
waitingDialog.hide()
res=false
},
error:function(a,b,c) {
waitingDialog.hide()
res=false
}
)
}
},
failure:function()
{
waitingDialog.hide()
res=false
},
error:function(a,b,c) {
waitingDialog.hide()
res=false
}
)
}
},
failure:function()
{
waitingDialog.hide()
res=false
},
error:function(a,b,c) {
waitingDialog.hide()
res=false
}
)
$("#modal_loader").modal('hide')
return res;//if true change step
}
}
У меня есть три использования beforeSend, чтобы показать диалоговое окно ожидания, также у меня есть трижды использовать setTimeout, но диалоговое окно ожидания не отображается, и умный мастер не идет вперед
Надеюсь, вы можете помочь, я новичок в jquery.
Извините за плохой английский
1 ответ
Предполагая, что вы используете jQuery-Smart-Wizard, решение заключается в:
- строительство вашего
onLeaveStep
обработчик событий, и (или включая) - измененная версия кода проверки, показанная в вопросе.
К счастью, несмотря на то, что плагин изначально не поддерживает асинхронность, сделать это довольно просто. По сути, то, что вам нужно сделать, это:
- возвращать
false
отonLeaveStep
Перезвоните, - установить обещание, которое будет выполнено при успешной валидации или отклонено при неудаче,
- звонить
.smartWizard('goForward')
из обработчика успеха обещания, - звонить
.smartWizard('showError')
из обработчика ошибок обещания.
Основанный на readMe.md от SmartWizard, вот структура для выполнения синхронных и асинхронных проверок:
$(document).ready(function() {
var waitingDialog = $('#whatever'); // ???
// Smart Wizard
$('#wizard').smartWizard({
onLeaveStep: leaveAStepCallback,
onFinish: onFinishCallback
});
function leaveAStepCallback(obj, context) {
alert("Leaving step " + context.fromStep + " to go to step " + context.toStep);
var returnValue;
switch(context.fromStep) {
case 1: // asynchronous
if (validator.checkAll($("#install_modbus_form"))) {
$("#modal_loader").modal();
waitingDialog.show();
validateStep1() // validateStep1() returns a promise
.then(function() {
// You will arrive here only if all three ajax calls were successful and all three responded with a truthy `response.success`.
$('#wizard').smartWizard('goForward'); // advance to next step
}, function(e) {
// You will arrive here on validation failure
$('#wizard').smartWizard('showError', e.message); // something went wrong
}).always(function() {
// You will arrive here on validation success or failure
waitingDialog.hide(); // the waiting is over
$("#modal_loader").modal('hide'); // ???
});
} else {
$('#wizard').smartWizard('showError', 'validator.checkAll() failed');
}
returnValue = false; // *must* return false to remain at step 1. If validation is successful, `.smartWizard('goForward')` will be executed later (see above).
break;
case 2: // synchronous
returnValue = validateStep2(); // validateStep2() returns true of false
break;
case 3:
...
break;
}
return returnValue; // true or false
}
// And here's the all-important `validateStep1()` :
function validateStep1() {
var sequence = [
{ url: 'url/1', data: {...} },
{ url: 'url/2', data: {...} },
{ url: 'url/3', data: {...} }
];
return sequence.reduce(function(promise, item, i) {
return promise.then(function() {
return $.ajax({
'type': 'post',
'url': item.url,
'dataType': 'json',
'data': item.data
}).then(function(response, textStatus, jqXHR) {
return response.success ? response : $.Deferred().reject(jqXHR, 'response.success not truthy at validation stage ' + i); // note: need to mimic jQuery.ajax's error signature.
});
});
}, $.when()) // starter promise for the reduction
.then(null, function(jqXHR, textStatus, errorThrown) {
return $.Deferred().reject(new Error(textStatus || errorThrown));
});
}
function validateStep2() {
// if validation here is synchronous, then return true of false
if(....) {
return true;
} else {
return false;
}
}
function validateStep3() {
...
}
// etc.
function onFinishCallback(objs, context) {
if(validateAllSteps()) {
$('form').submit();
}
}
function validateAllSteps() {
var isStepValid = true;
// all step validation logic
return isStepValid;
}
});
Заметки:
- логика ветвления находится в
onLeaveStep
Перезвоните. validateStep1()
использует последовательность обещаний для последовательности трех вызовов ajax.- если
validateAllSteps()
необходимо повторить проверку шага 1, тогда вам нужно будет позвонитьvalidateStep1().then(...)
снова или цепочка из ранее кэшированного обещания.
Как вы можете видеть, некоторые аспекты, перечисленные выше, являются неполными, поэтому еще есть над чем поработать.