校验错误

写在前面

JSON Schema 校验过程中会生产一组错误信息,每一个错误都有一个固定的 keyword 来表示,允许通过全局配置来覆盖 errors 默认的错误信息,包括处理错误信息国际化问题。例如当某属性为必填性时产生的错误信息为:

[{
  "keyword": "required",
  "dataPath": ".client",
  "schemaPath": "#/required",
  "params": {"missingProperty":"client"},
  "message":"必填项"
}]

其中 message 用于页面渲染的错误文本。

注:第一次渲染会触发校验,但不会有任何视觉展示,若需要一开始就体现错误视觉效果可以指定 <sf firstVisual>

自定义错误文本

分别支持全局配置 errors(一般用于国际化) 或 ui.errors(针对某个属性) 结构来处理错误文本。

ui.errors

schema: SFSchema = {
  properties: {
    email: {
      type: 'string',
      title: '邮箱',
      format: 'email',
      maxLength: 20,
      ui: {
        errors: {
          'required': '必填项'
        }
      }
    }
  }
};

keyword

不管采用哪种方式来构建错误文本,都必须通过 keyword 来区分错误类型(完整类型见 ERRORSDEFAULT)。

自定义校验

JSON Schema 校验并不一定能够满足一些业务的需求,例如需要根据其他属性值区分不同校验规则:

属性校验

schema: SFSchema = {
  properties: {
    type: {
      type: 'string',
      title: 'Type',
      enum: [
        { value: 'mobile', label: 'Mobile' },
        { value: 'email', label: 'email' },
      ],
      default: 'mobile',
    },
    mobile: {
      type: 'string',
      title: 'Mobile',
      ui: {
        visibleIf: { type: ['mobile'] },
        showRequired: true,
        validator: val => (!val ? [{ keyword: 'required', message: 'Required mobile' }] : []),
      },
    },
    email: {
      type: 'string',
      title: 'Email',
      ui: {
        visibleIf: { type: ['email'] },
        showRequired: true,
        validator: val => (!val ? [{ keyword: 'required', message: 'Required email' }] : []),
      },
    },
    pwd: {
      type: 'string',
      title: 'Password',
      ui: {
        type: 'password',
      },
    },
  },
  required: ['type', 'pwd'],
};

异步校验

例如一个异步校验用户名是否存在示例:

schema: SFSchema = {
  properties: {
    name: {
      type: 'string',
      ui: {
        showRequired: true,
        validator: (value: any) => this.http.get(`/user/check/${value}`).pipe(
          map(res => res ? [ { keyword: 'required', message: '用户名已存在'} ] : [])
        )
      }
    }
  }
};

注意: 由于每一次校验都是重新实例一次,因此无法做一些控制的操作,例如:去抖 debounceTime

setErrors

利用 setErrors 方法来调整错误信息。

this.sf.getProperty('/name')?.setErrors({ keyword: 'required' });
this.sf.getProperty('/name')?.setErrors({ message: 'Please input your username!' });
// 清理当前错误消息
this.sf.getProperty('/name')?.setErrors();

视觉

可以通过设置全局配置ui.onlyVisual 属性控制只展示错误视觉不显示错误文本。

Debug

JSON Schema 对格式有严格的要求,例如日期格式必须遵守 RFC3339 时间格式:

{
  properties: {
    time: {
      type: 'string',
      ui: { widget: 'date', mode: 'range' },
      title: 'Date',
      format: 'yyyy-MM-dd HH:mm:ss'
    }
  },
  ui: {
    debug: true
  }
}

其中 format 是一个错误时间格式,当指定 debug: true 时,会在控制台接收到详细的校验错误描述:

Error: unknown format "yyyy-MM-dd HH:mm:ss" is used in schema at path "#/properties/time"