承诺作出的处理多个Ajax请求确实很微不足道,但是“部分形式”对GUI设计的影响可能更具挑战性。你必须要考虑的事情,如:
- 一种形式分为几个部分,或每部分一种形式?
- 从一开始就显示所有部分,或逐步显示它们?
- 锁定以前验证过的部分以防止验证后干预?
- 重新验证每个阶段的所有部分,或只是当前的部分?
- 一个整体提交按钮还是每个部分一个?
- 应如何标记提交按钮(以帮助用户了解他所参与的过程)?
假设(这是对我的情况,但也许不是OP),我们不知道答案,所有这些问题还没有,但他们可以体现在两个功能 - validateAsync()
和setState()
,既其中接受stage
参数。
这使我们能够编写一个广义的主例程,以满足未知的验证调用和各种GUI设计决策。
这一阶段唯一需要的假设是形式/部分的选择器。让我们假设它/它们都有class="partialForm"
:
$('.partialForm').on('submit', function(e) {
e.preventDefault();
$.when(setState(1)) // set the initial state, before any validation has occurred.
.then(validateAsync.bind(null, 1)).then(setState.bind(null, 2))
.then(validateAsync.bind(null, 2)).then(setState.bind(null, 3))
.then(validateAsync.bind(null, 3)).then(setState.bind(null, 4))
.then(function aggregateAndSubmit() {
var allData = ....; // here aggregate all three forms' into one serialization.
$.post('mainurl', allData, function(result) {
console.log(result);
});
}, function(error) {
console.log('validation failed at stage: ' + error.message);
// on screen message for user ...
return $.when(); //inhibit .fail() handler below.
})
.fail(function(error) {
console.log(error);
// on screen message for user ...
});
});
这句法方便在这里呼吁setState()
作为然后回调虽然它的(可能)同步
样品validateAsync()
:
function validateAsync(stage) {
var data, jqXHR;
switch(stage) {
case 1:
data = $("#form1").serialize();
jqXHR = $.ajax(...);
break;
case 2:
data = $("#form2").serialize();
jqXHR = $.ajax(...);
break;
case 3:
data = $("#form3").serialize();
jqXHR = $.ajax(...);
}
return jqXHR.then(null, function() {
return new Error(stage);
});
}
样品setState()
:
function setState(stage) {
switch(stage) {
case 1: //initial state, ready for input into form1
$("#form1").disableForm(false);
$("#form2").disableForm(true);
$("#form3").disableForm(true);
break;
case 2: //form1 validated, ready for input into form2
$("#form1").disableForm(true);
$("#form2").disableForm(false);
$("#form3").disableForm(true);
break;
case 3: //form1 and form2 validated, ready for input into form3
$("#form1").disableForm(true);
$("#form2").disableForm(true);
$("#form3").disableForm(false);
break;
case 4: //form1, form2 and form3 validated, ready for final submission
$("#form1").disableForm(true);
$("#form2").disableForm(true);
$("#form3").disableForm(true);
}
return stage;
}
书面setState()
,将需要jQuery插件.disableForm()
:
jQuery.fn.disableForm = function(bool) {
return this.each(function(i, form) {
if(!$(form).is("form")) return true; // continue
$(form.elements).each(function(i, el) {
el.readOnly = bool;
});
});
}
正如我所说,上述validateAsync()
和setState()
只是初步的样本。至少,你将需要:
- 割肉出局
validateAsync()
- 修改
setState()
以反映您所选择的用户体验。
感谢您的时间和麻烦。我在“消化”你的答案。 –