ohayolibs
Version:
Ohayo is a set of essential modules for ohayojp.
294 lines (221 loc) • 12.7 kB
Markdown
---
order: 2
title: Schema
type: Documents
---
## 写在前面
[JSON Schema](http://json-schema.org/) 是一种标准的定义 JSON 数据结构的规范,并不包含对这些规范转换成表单具体说明,`@ohayo/form` 也是根据自己的理解并结合 `ng-zorro-antd` 现有数据录入组件库产生的动态构建表单类库。
JSON Schema **始终**都必须有一个类型为 `type="object"` 作为**根节点**,因此一个最简单的 Schema 结构至少是:
```ts
schema = {
type: 'object', // 可有可无,默认会强制为 `object`
properties: {}
}
```
在描述 Schema 说明之前,有必要对表单元素与 Schema 之前的联系做一个系统性说明。
我们知道,表单是由一组HTML元素组件,每一个元素对应一个 Schema 属性,属性有自己的数据类型、格式信息、视觉信息等,但这些信息不足以表述 `ng-zorro-antd` 所提供的丰富API接口。为了更好利用这些API接口,`@ohayo/form` 除了实现绝大部分 JSON Schema 标准以外,额外唯一增加了一个 `ui` 属性用于表述属性如何渲染的问题。
### 无污染
当然若你对标准有非常严格,或者 JSON Schema 数据结构是来自后端的产生时,可以通过 `<sf [ui]="ui">` 来额外对当前 JSON Schema 添加 UI 渲染。例如:
```ts
schema = {
properties: {
url: {
type: 'string',
title: 'Web Site'
}
}
}
```
一个URL属性,若我们不希望用于添加 `https://` 前缀的情况下,就单纯的 JSON Schema 结构是无法表述,而 `nz-input` 又支持非常丰富的前后缀文本,则我们可以为 `ui` 定制并增加 `https://` 的前缀文本:
```ts
ui = {
$url: {
addOnBefore: 'https://'
}
}
```
ui 本身也是一个 JSON 结构,为了区分 JSON Schema 属性名的对应关系,**必须**统一对属性名加上 `$` 前缀;对于数组的元素对象必须使用 `$items` 替代。当KEY为 `*` 时表示对所有子表单元素都有效。
### 表单元素与数据结构的对应关系
一个完整的表单元素我们认为应该包含以下若干元素:

从左至向各元素描述:
| 结构源 | 参数 | 说明 | 类型 | 默认值 |
|-----|----|----|----|-----|
| Schema | `[required]` | 是否必填项 | `string[]` | - |
| Schema | `[title]` | 属性描述 | `string` | - |
| ui | `[optional]` | 标签可选信息 | `string` | - |
| ui | `[optionalHelp]` | 标签可选帮助 | `string, SFOptionalHelp` | - |
| ui | `[placeholder]` | 文字框中显示提示信息 | `string` | - |
| Schema | `[description]` | 属性目的性解释 | `string` | - |
| - | `[error]` | 错误信息 | `string` | - |
### 一点规范
- 所有 `key` 按驼峰式命名法
- 若你对 JSON Schema 很熟悉,则忽略 **不建议** 字样
## JSON Schema(SFSchema)
JSON Schema 有完整的对每个属性的规范描述,`@ohayo/form` 当前是基于 [draft-07](http://json-schema.org/) 规范,下列是规范具体说明:
### 常规类
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[type]` | 数据类型,支持 JavaScript 基础类型 | `number,string,boolean,object,array` | `object` |
| `[enum]` | 枚举,静态数据源 | `SFSchemaEnumType[]` | - |
### 数值类型
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[minimum]` | 最小值 | `number` | - |
| `[exclusiveMinimum]` | 约束是否包括 `minimum` 值 | `boolean` | - |
| `[maximum]` | 最大值 | `number` | - |
| `[exclusiveMaximum]` | 约束是否包括 `maximum` 值 | `boolean` | - |
| `[multipleOf]` | 倍数 | `number` | - |
**关于exclusiveMinimum和exclusiveMaximum**
`sf` 的实现机制导致无法很好的处理 `type` 类型的错误捕获,因此默认情况下 `sf` 是忽略了所有 `type` (见 [config.ts](https://github.com/ohayojp/ohayo/blob/master/packages/form/src/config.ts#L12))类型错误,而这两种都错误都会被认为 `type` 类型错误,从而导致触发无效检查的原因。(更多细节请参考 [#676](https://github.com/ohayojp/ohayojp/issues/676#issuecomment-420208459))
### 字符串类型
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[maxLength]` | 定义字符串的最大长度 | `number` | - |
| `[minLength]` | 定义字符串的最小长度 | `number` | - |
| `[pattern]` | 验证输入字段正则表达式字符串,若指定 `format: 'regex'` 时务必指定 | `string` | - |
### 数组类型
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[items]` | 数组元素类型描述,只支持数组对象,若需要基础类型数组可通过其他部件支持 | `SFSchema` | - |
| `[minItems]` | 约束数组最小的元素个数 | `number` | - |
| `[maxItems]` | 约束数组最大的元素个数 | `number` | - |
| `[uniqueItems]` | 约束数组每个元素都不相同 | `boolean` | - |
| `[additionalItems]` | 数组额外元素的校验规则 | `SFSchema` | - |
### 对象类型
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[maxProperties]` | 最大属性个数,必须是非负整数 | `number` | - |
| `[minProperties]` | 最小属性个数,必须是非负整数 | `number` | - |
| `[required]` | 必需属性 | `string[]` | - |
| `[properties]` | 定义属性 | `{ [key: string]: SFSchema }` | - |
### 条件类
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[if]` | 条件验证 | `SFSchema` | - |
| `[then]` | 条件验证 | `SFSchema` | - |
| `[else]` | 条件验证 | `SFSchema` | - |
条件类的校验非常强大和丰富,但是出于会破坏UI导致整个组件构建更复杂,`@ohayo/form` 仅实现 `required` 的处理,并且把它当成是否显示校验目标,比如:一个登录页,会根据不同登录方式来显示不同登录模式:
```ts
schema: SFSchema = {
properties: {
type: { type: 'string', enum: [ 'mobile', 'name' ], default: 'mobile' },
name: { type: 'string' },
pwd: { type: 'string' },
mobile: { type: 'string' },
code: { type: 'string' }
},
required: [ 'type' ],
if: {
properties: { type: { enum: [ 'mobile' ] } }
},
then: {
required: [ 'mobile', 'code' ]
},
else: {
required: [ 'name', 'pwd' ]
}
};
```
上述的最终行为是当登录方式为 `mobile` 时UI显示 `mobile` 和 `code`,反之UI显示 `name` 和 `pwd`。
其实条件类最终被解析成 `ui.visibleIf`,在未来可能会增加条件类的处理。
### 逻辑类
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[allOf]` | **不建议** 使用,可用 `required` 替代 | `SFSchema[]` | - |
| `[anyOf]` | **不建议** 使用,可用 `required` 和 `minProperties` 替代 | `SFSchema[]` | - |
| `[oneOf]` | **不建议** 使用,值必须是其中之一 | `SFSchema[]` | - |
> **不建议** 主要是并没有对逻辑类进行UI相关处理,它同条件类类似,会影响UI渲染。
### 格式与视觉类
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[title]` | 属性描述 | `string` | - |
| `[description]` | 属性目的性解释 | `string` | - |
| `[default]` | 默认值 | `any` | - |
| `[readOnly]` | 是否只读状态,等同 `nzDisabled` | `boolean` | - |
| `[format]` | 数据格式,[文档](http://json-schema.org/latest/json-schema-validation.html#rfc.section.7.3) | `string` | - |
### 其他
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[definitions]` | 内部类型定义体 | `SFSchemaDefinition` | - |
| `[$ref]` | 引用定义体 | `string` | - |
| `[$comment]` | 针对开发者的注释,无任何意义,也不会被校验 | `string` | - |
### 非标准
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[ui]` | 指定UI配置信息,优先级高于 `sf` 组件 `ui` 属性值 | `SFUISchemaItem` | - |
## UI(SFUISchemaItem)
UI Schema 结构由通用性和小部件API两部分组成,以下是通用性部分进行接口说明,小部件部分自行参数小部件API。
> 为了小部件的API完整性,小部件Schema说明可能也会包含下列通用性部分。
### SFUISchema
等同 `<sf [ui]="ui">` 一组与 JSON Schema 结构相对应的 UI 结构体,类型为:`[ key: string ]: SFUISchemaItem`。
### 基础类
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[debug]` | 调试模式 | `boolean` | - |
| `[order]` | 属性顺序 | `string[]` | - |
| `[asyncData]` | 异步静态数据源 | `(input?: any) => Observable<SFSchemaEnumType[]>` | - |
| `[hidden]` | 是否隐藏渲染 | `boolean` | `false` |
| `[visibleIf]` | 指定条件时才显示 | `{ [key: string]: any[] | ((value: any) => boolean) }` | - |
| `[acl]` | ACL权限,等同 `can()` 参数值 | `ACLCanType` | - |
**visibleIf**
指定条件时才显示,例如:
- `visibleIf: { shown: [ true ] }`:当 `shown: true` 时才显示当前属性
- `visibleIf: { shown: [ '$ANY$' ] }`:当 `shown` 包括任意值时
- `visibleIf: { shown: (value: any) => value > 0 }`:复杂表达式
### 校验类
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[liveValidate]` | 是否实时校验 | `boolean` | `true` |
| `[firstVisual]` | 是否立即呈现错误视觉 | `boolean` | `false` |
| `[onlyVisual]` | 是否只展示错误视觉不显示错误文本 | `boolean` | `false` |
| `[ingoreKeywords]` | 忽略某些数据类型校验 | `string[]` | |
| `[errors]` | 自定义错误信息文本 | `{ [ key: string ]: string | ((obj: ErrorData) => string) }` | - |
| `[showRequired]` | 是否展示必填项标识 `*` | `boolean` | - |
| `[validator]` | 自定义校验 | `(value: any, formProperty: FormProperty, form: PropertyGroup) => ErrorData[]` | - |
### 数组类
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[items]` | 指定子元素的UI | `SFUISchema` | - |
| `[addTitle]` | 指定添加按钮文本 | `string` | `添加` |
| `[addType]` | 指定添加按钮风格,等同按钮 `nzType` | `string` | `dashed` |
| `[removable]` | 指定是否显示移除按钮 | `boolean` | - |
| `[removeTitle]` | 指定移除按钮文本 | `string` | `移除` |
### 表单元素类
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[type]` | 指定 `input` 的 `type` 值 | `string` | `text` |
| `[placeholder]` | 文字框中显示提示信息 | `string` | - |
| `[autofocus]` | 加载时是否获得焦点 | `boolean` | - |
### 渲染类
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[widget]` | 指定采用什么小部件渲染 | `string` | - |
| `[i18n]` | 指 `schema.title` 的国际化键值 | `string` | - |
| `[descriptionI18n]` | 指 `schema.description` 的国际化键值 | `string` | - |
| `[class]` | 自定义类,等同 `[ngClass]` 值 | `string,string[]` | - |
| `[width]` | 指定宽度,单位:`px` | `number` | - |
| `[size]` | 元素组件大小 | `default,large,small` | - |
| `[grid]` | 响应式属性 | `SFGridSchema` | - |
| `[optional]` | 标签可选信息 | `string` | - |
| `[optionalHelp]` | 标签可选帮助 | `string, SFOptionalHelp` | - |
### 响应式属性 SFGridSchema
`grid` 属性等同完整的 [Grid栅格系统](https://ng.ant.design/components/grid/zh),透过 `grid` 可以决定表单如何渲染。
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[gutter]` | 栅格间隔 | `number` | - |
| `[span]` | 每个表单元素栅格占位格数,为 `0` 时相当于 `display: none` | `number` | - |
| `[xs]` | `<768px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | `number, SFGridSizeSchema` | - |
| `[sm]` | `≥768px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | `number, SFGridSizeSchema` | - |
| `[md]` | `≥992px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | `number, SFGridSizeSchema` | - |
| `[lg]` | `≥1200px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | `number, SFGridSizeSchema` | - |
| `[xl]` | `≥1600px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | `number, SFGridSizeSchema` | - |
| `[xxl]` | 保留字段,`0.7.0` 后支持 | `number, SFGridSizeSchema` | - |
### 水平布局类 Schema
> **务必**二者总和为 `24`
| 参数 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[spanLabel]` | `label` 所占栅格数 | `number` | 5 |
| `[spanControl]` | 表单控件所占栅格数 | `number` | 19 |
| `[offsetControl]` | `control` 栅格左侧的间隔格数,间隔内不可以有栅格 | `number` | - |
| `[spanLabelFixed]` | `label` 固定宽度 | `number` | - |