extjs6.5异步远程验证

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;
}

猜你喜欢

转载自haohetao.iteye.com/blog/2398345
6.5