阅读更多
extjs 6.5本身不支持异步验证,只能执行js验证,异步验证需要自己实现
在一个Ext.data.validator里面执行Ajax请求,请求执行成功后执行回调函数,然后调用Ext.field.Field的setError方法显示错误并阻止表单提交。
关于setError和isValid可以参考源码
/**
* This method is called by {@link #method!validate validate} if the value is both
* non-empty (not `null`, `undefined` or `''`) and if the value can be parsed by the
* {@link #method!parseValue parseValue} method. This parsing concern is technically
* only in play for `Ext.field.Text` and derived classes (such as `Ext.field.Date` and
* `Ext.field.Number`) but the guarantee here is that the `value` will be a parsed
* value and not the raw string and if the value cannot be parsed, this method will
* not be called.
*
* @param {Mixed} value The (parsed) value
* @param {String[]} errors The array of validation errors
* @param {Boolean} [skipLazy] `false` (the default) to run all validators.
* @private
*/
doValidate: function (value, errors, skipLazy) {
var validators = this.getValidators(),
len = validators && validators.length,
i, result, validator;
for (i = 0; i
validator = validators[i];
if (!skipLazy || !validator.lazy) {
result = validator.validate(value);
if (result !== true) {
//
if (!result || typeof result !== 'string') {
Ext.raise('Validator did not return a valid result.');
}
//
errors.push(result);
}
}
}
},
parseValue: Ext.identityFn, // documented on textfield
/**
* Validate the field and return it's validity state.
* To get the existing validity state without re-validating current value,
* use {@link isValid}.
*
* @param {Boolean} [skipLazy] (private) Pass `true` to skip validators marked as `lazy`.
* @return {Boolean} The new validity state.
*/
validate: function (skipLazy) {
var me = this,
empty, errors, field, record, validity, value;
// If we are in configuration and not validating any values, skip out of here
if (me.isConfiguring && me.validateOnInit === 'none') {
return true;
}
// if field is disabled and cfg not set to validate if disabled, skip out of here
if (!me.getDisabled() || me.getValidateDisabled()) {
errors = [];
// If we are a textual input field, get the input element's value.
// Check the DOM validity state first in case a type="number"
// check has failed.
if (me.isInputField && !me.isSelectField) {
value = me.getInputValue();
empty = !value;
validity = empty && me.inputElement.dom.validity;
if (validity && validity.badInput) {
errors.push(me.badFormatMessage);
empty = false;
}
}
else {
value = me.getValue();
empty = value === '' || value == null;
}
if (empty && me.getRequired()) {
errors.push(me.getRequiredMessage());
}
else if (!errors.length) {
if (!empty) {
// Pass non-empty values along to parseValue to handle things like
// datefield and numberfield. Technically this concern is more of a
// textfield family issue, but it is awkward to leap out of this
// sequence in such a way as to make a surgical override practical...
// So we simply provide identityFn as the default parseValue impl
value = me.parseValue(value, errors);
}
if (!errors.length) {
field = me._validationField;
record = me._validationRecord;
if (field && record) {
field.validate(value, null, errors, record);
}
if (!empty) {
me.doValidate(value, errors, skipLazy);
}
}
}
if (errors.length) {
me.setError(errors);
return false;
}
}
me.setError(null);
return true;
},
当有错误显示时调用isValid就会为true,isValid的逻辑如下
/**
* Mark field as invalid.
* @deprecated 6.5.0 Use {@link #setError} instead. (for classic compatibility)
* @since 6.5.0
*/
markInvalid: function (messages) {
this.setError(messages);
},
/**
* Mark field as valid.
* @deprecated 6.5.0 Use {@link #setError setError(null)} instead. (for classic compatibility)
* @since 6.5.0
*/
clearInvalid: function () {
this.setError(null);
},
/**
* Returns true if field is valid.
*/
isValid: function () {
return !this.getError();
},
为了使ajax回调时能获得field的引用需要修改doValidate的代码,把field的引用传递过去
result = validator.validate(value,this);
[code="js"]/**
* Created by hetao on 2017/10/12.
*/
Ext.define('overrides.field.Field', {
override:'Ext.field.Field',
/**
* This method is called by {@link #method!validate validate} if the value is both
* non-empty (not `null`, `undefined` or `''`) and if the value can be parsed by the
* {@link #method!parseValue parseValue} method. This parsing concern is technically
* only in play for `Ext.field.Text` and derived classes (such as `Ext.field.Date` and
* `Ext.field.Number`) but the guarantee here is that the `value` will be a parsed
* value and not the raw string and if the value cannot be parsed, this method will
* not be called.
*
* @param {Mixed} value The (parsed) value
* @param {String[]} errors The array of validation errors
* @param {Boolean} [skipLazy] `false` (the default) to run all validators.
* @private
*/
doValidate: function (value, errors, skipLazy) {
var validators = this.getValidators(),
len = validators && validators.length,
i, result, validator;
console.log(this);
for (i = 0; i
if (!result || typeof result !== 'string') {
Ext.raise('Validator did not return a valid result.');
}
//
errors.push(result);
}
}
}
},
});
然后自己定义验证器里面这样写
validate: function(value,formField) {
Ext.Ajax.request({
url : 'rest/users?action=validate&username=' + newValue,
scope:formField,
success : function(response) {
// Ausuming responseText is {"valid" : true}
var validFlag = Ext.decode(response.responseText).valid ? true : 'The username is duplicated!';
if(validFlag!=true)
{
this.setError(validFlag);
}
}
return true;
}
return true;
}