jquery validate的一个坑,在使用remote远程验证方法的时候,会有缓存,当需要验证的元素的值没发生改变时会使用缓存的验证结果返回。
场景描述:
身份证号码需要进行重复验证,使用remote远程验证方法,更换岗位类型需要重新进行验证。
改变岗位类型,但是身份证号码的remote验证没有触发远程调用,但是validate自带的验证(idCard,required等)都触发了,难道valid() 方法 触发不了 remote?
看一下jquery.validate.js的源码,找到remote方法:
//version 1.13.1
remote: function( value, element, param ) {
if ( this.optional( element ) ) {
return "dependency-mismatch";
}
var previous = this.previousValue( element ),
validator, data;
if (!this.settings.messages[ element.name ] ) {
this.settings.messages[ element.name ] = {};
}
previous.originalMessage = this.settings.messages[ element.name ].remote;
this.settings.messages[ element.name ].remote = previous.message;
param = typeof param === "string" && { url: param } || param;
if ( previous.old === value ) {
return previous.valid;
}
previous.old = value;
validator = this;
this.startRequest( element );
data = {};
data[ element.name ] = value;
$.ajax( $.extend( true, {
url: param,
mode: "abort",
port: "validate" + element.name,
dataType: "json",
data: data,
context: validator.currentForm,
success: function( response ) {
var valid = response === true || response === "true",
errors, message, submitted;
validator.settings.messages[ element.name ].remote = previous.originalMessage;
if ( valid ) {
submitted = validator.formSubmitted;
validator.prepareElement( element );
validator.formSubmitted = submitted;
validator.successList.push( element );
delete validator.invalid[ element.name ];
validator.showErrors();
} else {
errors = {};
message = response || validator.defaultMessage( element, "remote" );
errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message;
validator.invalid[ element.name ] = true;
validator.showErrors( errors );
}
previous.valid = valid;
validator.stopRequest( element, valid );
}
}, param ) );
return "pending";
}
如果当前的值没有发生改变,直接返回上一次的验证结果,坑找到了。。。
如此大坑,jquery难道没有修复,难道是版本问题。让我们再看一下 validate 1.7的remote方法
//version 1.7
remote: function(value, element, param) {
if (this.optional(element))
return "dependency-mismatch";
var previous = this.previousValue(element);
if (!this.settings.messages[element.name])
this.settings.messages[element.name] = {};
previous.originalMessage = this.settings.messages[element.name].remote;
this.settings.messages[element.name].remote = previous.message;
param = typeof param == "string" && { url: param} || param;
if (previous.old !== value) {
previous.old = value;
var validator = this;
this.startRequest(element);
var data = {};
data[element.name] = value;
$.ajax($.extend(true, {
url: param,
mode: "abort",
port: "validate" + element.name,
dataType: "json",
data: data,
success: function(response) {
validator.settings.messages[element.name].remote = previous.originalMessage;
var valid = response === true;
if (valid) {
var submitted = validator.formSubmitted;
validator.prepareElement(element);
validator.formSubmitted = submitted;
validator.successList.push(element);
validator.showErrors();
} else {
var errors = {};
var message = (previous.message = response || validator.defaultMessage(element, "remote"));
errors[element.name] = $.isFunction(message) ? message(value) : message;
validator.showErrors(errors);
}
previous.valid = valid;
validator.stopRequest(element, valid);
}
}, param));
return "pending";
} else if (this.pending[element.name]) {
return "pending";
}
return previous.valid;
}
修复了防止在remote方法执行完之前,继续发起第二次请求,有可能导致验证错误的风险,但是并没有解决缓存的问题。
只能自己解决了, 查看previous.old的来源
previousValue: function(element) {
return $.data(element, "previousValue") || $.data(element, "previousValue", {
old: null,
valid: true,
message: this.defaultMessage(element, "remote")
});
}
是表单元素的previousValue数据,手动清除一下即可