我有一些jQuery,它使用每个循环来遍历Symfony 3 CRM上重复表格字段中输入的值。有一个$.post
会将输入的值发送到一个函数,该函数检查数据库中是否存在重复项,如果是重复项,则会向数组中添加某些内容,否则将添加空白值以表明它不是重复项。完成这些操作后,它将检查最终数组,并将所有错误添加到错误块以显示给用户。
但是,数组似乎总是空白,我相信它是因为它正在运行显示错误的代码,然后才真正完成响应。
这是我的代码:
$('#puppy_form').on('submit', function() {
var bitch_errors = [];
var dog_errors = [];
// NOTE: Bitch and dog names need to be checked differently so we know which error is assigned to which input
$('.check_bitch_name').each( function(i, obj) {
// need to check each name for validity and duplication.
var entered_bitch_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_bitch_name)) {
bitch_errors[i+1] = "invalid";
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_bitch_name }
).done(function (response) {
if(response == 'duplicate') {
bitch_errors[i+1] = "duplicate";
} else {
bitch_errors[i+1] = "";
}
});
}
});
$('.check_dog_name').each( function(i, obj) {
// need to check each name for validity and duplication.
var entered_dog_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_dog_name)) {
dog_errors[i+1] = "invalid";
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_dog_name }
).done(function (response) {
if(response == 'duplicate') {
dog_errors[i+1] = "duplicate";
} else {
dog_errors[i+1] = "";
}
});
}
});
if(count(bitch_errors) == 0 && count(dog_errors) == 0) {
return true;
}
// loop through the errors and assign them to the correct input
$.each( bitch_errors, function( key, value ) {
if (value == "invalid") {
$('input[name="bitch_name['+key+']"]').parent().addClass('has-error');
$('input[name="bitch_name['+key+']"]').next('.error-message').html('Names must be at least two words, and only contain letters');
return false;
} else if(value == "duplicate") {
$('input[name="bitch_name['+key+']"]').parent().addClass('has-error');
$('input[name="bitch_name['+key+']"]').next('.error-message').html('Sorry, this name has already been taken');
return false;
}
});
$.each( dog_errors, function( key, value ) {
if(value != "") {
if (value == "invalid") {
$('input[name="dog_name['+key+']"]').parent().addClass('has-error');
$('input[name="dog_name['+key+']"]').next('.error-message').html('Names must be at least two words, and only contain letters');
return false;
} else if(value == "duplicate") {
$('input[name="dog_name['+key+']"]').parent().addClass('has-error');
$('input[name="dog_name['+key+']"]').next('.error-message').html('Sorry, this name has already been taken');
return false;
}
}
});
return false;
});
基本上,它首先检查输入的名称是否有效,然后过帐并检查是否存在重复。问题是,即使它进行了有效性检查(并相应地打印了错误),它似乎也忽略了重复检查,并在它还没有返回第一个响应之前就继续执行。
我如何确保在完成检查之前完成检查并将错误添加到表单?我尝试了其他解决方案,包括尝试在jQuery中实现
$.when
功能,但我不太了解如何使其正常工作。任何帮助表示赞赏。 最佳答案
首先,编写一个返回异步承诺的函数,为您提供一条狗的价值:
function checkDog(name) {
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(name)) {
return $.Deferred().resolve("invalid");
} else {
return $.post('/check-puppy-name', { name: name } )
.then(function (response) {
if (response === 'duplicate') {
return 'duplicate';
} else {
return '';
}
});
}
}
然后,您可以编写一个处理多只狗的代码,并返回一个承诺(只有在检查完每只狗之后,它才会被解决):
function checkDogs(array) {
return $.when.apply($, array.map(checkDog));
}
注意,还没有与DOM相关的代码。现在,您可以编写一个函数,该函数从一堆DOM输入中获取值并以数组形式返回它们:
function getInputValues($selector) {
return $selector.get().map(function(el) {
return el.value;
});
}
因此,现在(在
submit
上),您可以检查两组输入,然后最后在两个输入都可用时,可以检查结果并更新DOM:$('#puppy_form').on('submit', function() {
var bitch_names = getInputValues($('.check_bitch_name'));
var dog_names = getInputValues($('.check_dog_name'));
var bitch_promises = checkDogs(bitch_names);
var dog_promises = checkDogs(dog_names);
$.when(bitch_promises, dog_promises).then(function(bitch_errors, dog_errors) {
// update the DOM based on the passed arrays
...
});
});