UNPKG

@zenweb/form

Version:

Zenweb Form module

119 lines (118 loc) 2.94 kB
import { ResultFail } from '@zenweb/result'; import { typeCast } from 'typecasts'; import { Widget } from './widget.js'; export class FieldFail extends ResultFail { mcode; constructor(mcode, extra, data) { super({ message: mcode, extra, data, }); this.mcode = mcode; } } /** * 使用链式编程生成带有类型标注的字段 */ export class Field extends Widget { _valueType; _validate; _splitter; _maxItems; _minItems; _default; /** * 是否为必填项 */ _required; /** * 是否允许 null 值 */ _nullable; constructor(_valueType) { super(); this._valueType = _valueType; this._required = _valueType.startsWith('!'); this._nullable = !_valueType.startsWith('!') && !_valueType.startsWith('?'); } /** * 设置默认值 */ default(value) { this._default = value; return this; } /** * 数据项验证 */ validate(opt) { this._validate = Object.assign({}, this._validate, opt); return this; } /** * 设置列表分隔符 * - 类型为列表时有效 * - 如果原始数据为字符串时使用的切割符 * @param sep 默认 `,` */ splitter(sep) { this._splitter = sep; return this; } /** * 限制列表最大数量 */ maxItems(count) { this._maxItems = count; return this; } /** * 限制列表最小数量 */ minItems(count) { this._minItems = count; return this; } /** * 验证失败 - 抛出异常 */ fail(code, params) { throw new FieldFail(code, params); } /** * 数据验证清理 * - 在字段数据验证通过后调用 * - 如果验证不通过需要抛出异常可以使用 `this.fail('code')` * - 需要返回清理完成的数据 */ clean(data) { return typeCast(data, { type: this._valueType, default: this._default, validate: this._validate, splitter: this._splitter, maxItems: this._maxItems, minItems: this._minItems, }); } output(formData, fieldName) { return Object.assign({}, super.output(), { required: this._required, nullable: this._nullable, valueType: this._valueType, // default: (this._data ? propertyAt(this._data, name.split(objectSpliter)) : null) || opt.cast.default, default: (formData && fieldName && fieldName in formData) ? formData[fieldName] : this._default, validate: this._validate, }); } } /** * 使用函数方式初始化字段类 * @param clazz 字段类 */ export function simple(clazz) { return (valueType) => { return new clazz(valueType); }; }