# 自定义验证

在流程应用中,自定义验证为复杂的验证需求提供了灵活的解决方案。通过自定义验证函数,可以实现对输入内容的复杂验证逻辑,甚至调用后台服务进行验证。本文将详细介绍如何实现自定义验证,并分享如何将通用的验证函数提取到基础类中以便复用。

# 1. 自定义验证的需求场景

例如,新产品登记表单中需要输入一个产品代号,要求:

  1. 以字母开头,可以包含数字。
  2. 不能包含 Windows 文件名中不允许的字符(如 \, /, :, *, ?, ", <, >, |)。

这种需求无法通过常规的必填验证、比较验证或格式验证实现,需要使用 自定义验证

# 2. 自定义验证的实现步骤

# 2.1 添加字段

  1. 在表单上添加一个字段,命名为“产品代号”。

# 2.2 设置自定义验证

  1. 选择“产品代号”字段,进入 高级验证
  2. 点击 新增验证,选择 自定义验证
  3. 自定义验证函数名 中输入函数名称,例如 ProdCode

自定义验证设置 ▲ 自定义验证设置

# 2.3 编写自定义验证函数

  1. 打开表单的 源码,找到 validators 部分。
  2. validators 中添加自定义验证函数 ProdCode
  3. 编写验证逻辑,例如:

编写自定义验证函数 ▲ 编写自定义验证函数

自定义验证函数ProdCode的逻辑代码:


validators: {
    ProdCode: function(value, field) {
        // 定义 Windows 文件名中不允许的字符
        const invalidChars = '\\/:*?"<>|';
        // 定义不允许字符的正则表达式
        const invalidCharsRegex = new RegExp(`[${invalidChars}]`);
        // 定义以字母开头,可包含数字的正则表达式
        const startsWithLetterRegex = /^[a-zA-Z][a-zA-Z0-9]*$/;

        // 检查物品编号是否为空
        if (!value) {
            return '产品代号不能为空';
        }

        // 检查是否包含不允许的字符
        if (invalidCharsRegex.test(value)) {
            const invalidChar = value.match(invalidCharsRegex)[0];
            return `产品代号不能包含字符 "${invalidChar}"`;
        }

        // 检查是否以字母开头
        if (!startsWithLetterRegex.test(value)) {
            return '产品代号必须以字母开头,且只能包含字母和数字';
        }

        // 验证成功
        return true;
    }
}

# 2.4 保存并测试

  1. 保存表单后,进入流程发起界面。
  2. 输入不符合要求的产品代号(如包含非法字符),提交表单,系统会阻止提交并显示错误提示。
  3. 输入符合要求的产品代号,提交表单,系统允许提交。

# 3. 调用后台服务的自定义验证

例如,验证输入的产品代号是否已被占用,需要调用后台服务进行验证。

# 实现方法

  1. 在自定义验证函数中,使用 Yiez.Ajax.request 调用后台服务。
  2. 示例代码:
    validators: {
        ProdCode: function(value, field) {
            ....
            var rv;
            Yiez.Ajax.request({
                method: 'GET',
                async: false, // 同步调用,验证方法必需同步调用
                url: Yiez.$url('bpm/validators/prodcode/{0}', [value]), // 传值方法1:url传值
                params: {
                    value: value // 传值方法2:查询参数传值
                },
                jsonData: {
                    value: value // 传值方法3:payload传值
                },
                success: function (action) {
                    rv = true; // 验证成功
                },
                failure: function (action) {
                    rv = action.result.errorMessage; // 验证失败,返回错误信息
                }
            });
            return rv; // 验证返回值,true或服务器端返回的errorMessage
            ...
        }
    }
    

# 注意事项

  • 后台服务需要实现相应的验证逻辑,并返回验证结果。
  • 验证函数必须同步调用(async: false),以确保验证结果能够及时返回。

# 4. 通用验证函数的复用

如果某个验证函数(如 ProdCode)需要在多个表单中使用,可以将该函数提取到表单的基础类中,以便复用。

# 实现方法

  1. 打开表单的 源代码,找到表单的基础类(如 Yiez.form.AbstractForm)。

  2. 在基础类的 validators 中添加自定义验证函数 ProdCode

  3. 示例代码:

       Ext.define('Yiez.form.AbstractForm',{
        ...
        validators: {
            ProdCode: function(value, field) {
                // 验证逻辑
            }
        }
       ...
    });
    
    
  4. 保存后,所有继承该基础类的表单都可以使用 ProdCode 验证函数。

# 优势

  • 避免在每个表单中重复定义相同的验证函数。
  • 便于维护和修改,只需修改基础类中的验证函数即可。

# 5. 总结

  • 自定义验证
    • 适用于复杂的验证需求,例如自定义格式、调用后台服务等。
    • 实现方法:在表单的 validators 中编写自定义验证函数。
  • 调用后台服务
    • 通过 Yiez.Ajax.request 调用后台服务进行验证。
  • 通用验证函数的复用
    • 将通用的验证函数提取到表单的基础类中,便于复用和维护。

通过合理使用自定义验证,可以满足各种复杂的验证需求,确保表单数据的准确性和业务规则的完整性。