@zenweb/form
Version:
Zenweb Form module
119 lines (118 loc) • 2.94 kB
JavaScript
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);
};
}