窗体引擎核心
开发维护文件
- 9.1 国家 数据上的窗体组
- 9.2 (中文(简体) ) valid 上的窗体组
方程式概览

Form-engine Basic arquiture是以类为主,由FormGroup,Form and Field等组成,通信是可观察的以基为主,以便喂养那些负责放出并重播在图上所配置的被动操纵的适配器.
每个类从下到上都是独立的,这意味着你可以独立地固定一个字段,但一个表单依赖于字段来工作,因为一个表单类管理着相互相互作用的字段,与依赖表单的表单组一样来工作.
FormGroup管理作为密钥/值映射而存储的窗体,与将字段存储为密钥/值映射的窗体相同.
窗体组应负责任
- 管理表单的添加和去除
- 管理用户插入表格的数据,以便向适配器提供回调
- 管理表格的有效性,为适配器提供回调
- 正在检查所需的功能
表单责任
- 管理字段的添加和去除按键
- 根据方案配置管理字段的能见度
- 基于计划配置管理重置 Values
- 管理跨字段释放的诱导属性变化
- 基于映射器列表配置管理组件配置
- 管理对字段发送的事件的回调订阅( 调整外部动作触发器)
- 管理表单值提交和有效性检查
表单字段责任
- 管理诸如验证、价值、错误信息等属性的存储和排放
- 管理请求的 api 方案配置
- 管理适配器初始化外部配置绑定通则
改变私人外地财产类别
在执行过程中,必须理解表格的反应取决于 RXJS 软件,这种属性变化会对其他属性造成副作用,所有属性都由 RXJS 软件 主题,所以对于所有这些类属性,每次它们改变,它们都需要向相应的主题发出,所以所有这些属性都有一个被发出到结尾的主体.
如果从事涉及这些财产的任何维护工作:
private _props: Record<string, unknown>;
private _value: unknown;
private _stateValue: Record<string, unknown>;
private _metadata: unknown;
private _visibility: boolean;
private _errors: TErrorMessages;
private _api: TApiResponse;
private _valid: boolean;
private _mounted: boolean;
他们都有一个 get 财务报告和审定财务报表 set 方法构造器
这个 get 构造者负责交付价值
这个 set 构造者负责在此私有属性上设定值,同时向相应的主体和窗体模板主体排放
private _stateValue: unknown;
private _metadata: unknown;
errorsString: string;
errorsList: string[];
这种财产是根据其他私有财产计算的,
_stateValue 将口罩应用到 _value 何时 set value 方法称为
_metadata 已发送元数据 变化事件 映射器在 set value 名为
何时 set errors 方法叫做, errorsString 是在字符串中缩合出错的信息列表,用逗号分隔 , 财务报告和审定财务报表 errorsList 是错误消息的列表
如果您尝试直接改变这个值而不使用它的构造器, 它会在形式反应上引起严重的问题, 即使是在最后使用的情况下, 谨慎地评价是否您应该直接在任何维护或特性执行上改变这个值
价值变化规则
如果您在数值变化上努力, 请考虑值变化被作为配置上的特殊属性处理, 让我们考虑在反应中某个组件会发生什么:
const [value, setValue] = useState('');
const handleChange = (e) => {
const val = e.currentTarget.value;
val ? (setValue = val) : '';
};
<input onChange={handleChange} value={value} />;
值道克被绑定在值态上,而onChange道克被绑定在会改变该值的函数上.
在形式引擎中,持有该价值的财产和改变该价值的财产是:
class FormField
private _value: unknown;
(...)
get value(): unknown {
return this._value;
}
set value(value: unknown) {
/*
too much unstable, if the valueChangeEvent parses the template event
value, might occur unexpected results
*/
let val;
if (this.valueChangeEvent) {
try {
val = this.valueChangeEvent(value, { props: this.props });
} catch (e) {
val = value;
}
} else {
val = value;
}
if (typeof val === 'undefined' || val === null) return;
if (typeof val === 'object' && '_value' in val && '_metadata' in val) {
this._value = this.formatValue(val['_value']);
this._stateValue = this.mapper.events?.setValue
? {
[this.mapper.events.setValue]: this.maskValue(
this.formatValue(val['_value'])
),
}
: {};
this._metadata = val._metadata;
} else {
this._value = this.formatValue(val);
this._stateValue = this.mapper.events?.setValue
? {
[this.mapper.events?.setValue]: this.maskValue(
this.formatValue(val)
),
}
: {};
this.maskValue(this.formatValue(val));
this._metadata = val;
}
this.stateValue && this.valueSubject$.next(this.stateValue);
this.templateSubject$.next({ key: this.name, event: 'ON_VALUE' });
}
在这种情况下,传递到这种设置方法的值可以有多种格式(这是 变化事件 负责在此每一种格式上传递值的映射函数 :
value: unknown;
该值被格式化并存储到 fieldinstance._value 和带有值的道具名称 fieldinstance._stateValue
{ _value: unknown, _metadata: unknown }
这个 _value 键已格式化并存储到 fieldinstance._value 和带有值的道具名称 fieldinstance._stateValue
这个 _metadata 密钥存储于 fieldinstance._metadata 并可以使用 fieldinstance.metadata 只读属性
但是,这种改变可以在Schema上定义副作用,比如验证,能见度条件等等,所以改变这个值并触发所有副作用的正确方式,以便更新使用这个实例的组件就是使用 fieldinstance.emitValue 类函数 :
fieldinstance.emitValue({ event: 'ON_FIELD_CHANGE', value: 'hello' });
此函数将设定值并触发所有副作用, 并触发定义的 OnData 回调 :
emitValue(prop: {
value: unknown | { _value: unknown; _stateValue: unknown };
event: TEvents;
}): void {
this.value = prop.value;
this.emitEvents({ event: prop.event });
this.dataSubject$.next({ key: this.name, event: prop.event });
}
emitEvents({ event }: { event: TEvents }): void {
this.setFieldValidity({ event });
this.validateVisibility({ event, key: this.name });
this.resetValue({ event, key: this.name });
this.apiEventQueueSubject$.next({ event });
this.fieldEventSubject$.next({
event,
fieldName: this.name,
fieldInstance: this,
});
}
要释放此值变化的抓取, 值设置在端部释放, 在配置的属性上设定值 mapper -> events -> setValue 当该值被取回时,会用已配置的通讯键创建对象,以在组件上作为道具传递.
另外,还有一个帮助器函数来帮助注册这个召回函数,它负责在调用适配器上更改这个值 subscribeValue。 。 。 .
因此,将基本反应执行从简单的绑定状态和更改处理器与形式引擎控制输入处理器进行比较,执行是这样的:
const [valueState, setValueState] = useState<Record<string, unknown>>(fieldinstance.stateValue || {});
fieldInstance = new FormField(
(...)
mapper: {
events: {
setValue: 'value'
}
}
(...)
)
useEffect(() => {
fieldInstance.subscribeValue((value) => setValueState(value));
return () => {
fieldInstance?.destroyField();
};
}, []);
const handleChange = useCallback((event: unknown) => {
fieldInstance?.emitValue({ value: event, event: 'ON_FIELD_CHANGE' });
}, []);
return <input onChange={handleChange} {...valueState}>
当字段挂起呼叫时, 收听者会注册 subscribeValue 用于更新状态的实地实例.
手柄切换调取字段实例 emitValue
管理验证,能见度等的其余过程在形式-引擎-核心(form-engine-core)上内部发生,适配器唯一需要做的就是告知设定为输入值的值,处理输出,并在效应所定义的回调函数上交付.
说明: 这是为演示目的, 适配器的最终执行 仅类似于此
倡导更改和能见度规则
道具的改变可以在计划上定义,也可以用诱导来改变,让我们考虑反应中发生的情况:
return <input label={props.label} placeholder={props.placeholder}>
反应每次改变道具时都会重置这个元件,如果是形式-引擎,这种道具会传到schema上,并且可以根据任何场面副作用改变的诱导,管理道具变化的是一个RXJS主题,以便正确登记道具,让形式-引擎管理副作用,这需要完成:
const [state, setState] = useState<Partial<IState>>({
visibility: fieldInstance?.visibility || true,
props: fieldInstance?.props || props,
});
useEffect(() => {
fieldInstance.subscribeState((props) => {
setState((prev) => ({
...prev,
...props,
}))
})
return () => {
fieldInstance?.destroyField();
};
},[])
return {state.visibility && <input {...props}>}
字段实例有一个帮助函数来注册回调函数 subscribeState 用于每次在窗体引擎上内部更改道具时调用,在这个调回功能上,您需要更改道具的状态,以便发生到适配器上,同样可见度控制由 visibility 由回调函数给出道具,所以要显示或隐藏元件的条件要根据这个道具值来制作到适配器上.
注:试图传递发送该值的值,除非该值是一个模板,否则不会成功
说明: 这是为演示目的, 适配器的最终执行 仅类似于此
显示错误消息
对于错误消息显示,基于配置到计划上的字段发生的验证逻辑,组件需要将属性配置到映射器配置上 mappers -> events -> setErrorMessage,然后,每次发生错误,字段都会自动在相应的道具上显示出错误.
反应中的基本成分示例:
const [errorMessage, setErrorMessage] = useState('')
return <Input errorMessage={errorMessage}>
在窗体引擎中,错误消息将在 errors 将道具名称传递到映射程序配置上, 以及所有被触发的错误消息
示例
fieldInstance = new FormField(
(...)
mapper: {
events: {
setErrorMessage: 'errorMessage'
}
}
(...)
)
const [state, setState] = useState<Partial<IState>>({
visibility: fieldInstance?.visibility || true,
props: fieldInstance?.props || props,
});
useEffect(() => {
fieldInstance.subscribeState((props) => {
setState((prev) => ({
...prev,
...props,
}))
})
return () => {
fieldInstance?.destroyField();
};
},[])
return <Input {...state.errors}>
错误将包含一个有密钥的对象 errorMessage 用逗号分隔出的所有出错, 配置到映射器上的密钥会根据组件道具的不同而变化, 如果另一个组件在另一个道具上设置出错消息, 则需要配置到映射器配置到设置的 ErrorMessage 事件内部 .
说明: 这是为演示目的, 适配器的最终执行 仅类似于此
主题依赖关系
字段
templateSubject$: Subject<TTemplateEvent>;
fieldEventSubject$: Subject<TFieldEvent>;
dataSubject$: Subject<{ key: string; event: TEvents }>;
formValidNotification$: Subject<Pick<TFormValidationPayload, 'fieldTrigger'>>;
此主题需要作为字段构造参数来传递,而字段引用符需要将它们固定,它们也是形式实例的一部分 执行
模板对象$
在任何字段突变时都需要引用这个主题,这将通知一个字段改变的表格,以及需要重算具有模板依赖性的任何其他字段,
实例: field1 标签道具取决于 field2 值,所以: field1.props.label 有模板 ${field2.props.value}时,每次 field2 价值变化,
页:1 templateSubject$ 发送,表格得到的通知和检查 field2 有一个 field1 依赖性和更新 label 包含值
联 合 国 field2
字段事件对象$
每次从一个组件映射出的基本事件发生时 onChange 或者说 onBlur 字段以事件类型和字段名称发布此主题,
如果适配器引用 subscribeFieldEvent 在带有回调函数的即时形式上,此函数每次字段都会被调用 emitEvents 被引用,否则被忽略
数据对象元
主题每次触发 emitValue 如果适配器引用 subscribeData 在即时表格上并传递回调函数,此函数将每次字段执行 emitValue 被引用
表格
如果适配器引用, 此主题每次发生字段验证状态变化时都会触发 subscribeFormValidation 在即时形式上具有回调函数,此函数将执行,每次字段有效性变化,给予形式有效性状态
以计划构建字段
简略地解释如果一个计划作为参数通过, 如何用一个计划来构建字段, 窗体的构造方法会注意过程
字段
每个方案都用表单实例来解析 serializeStructure 方法,此选项将选择所有字段, 将地图上的所有窗体字段即时化, 并准备与构造器上传递的主题与窗体相互作用, 适配器负责选择此字段映射和构建组件树, 您可以检查反应适配器 BuildTree 方法
模板
以注册模板,窗体实例 subscribeTemplates 需要引用,这将创建一个依赖性列表,每次检查一次 templateSubject$ ,请注意需要在所有字段被即时调用,否则所有模板可能不会相应注册
构建没有计划字段
如果您想要添加一个字段, 没有一个方案, 窗体实例有 addField 方法, 这将在窗体实例上添加一个字段, 并处理几个预先要求, 例如检查名称是否不存在并记录模板, 适配器有责任想出如何使这个字段打开
窗体组事件召回寄存器
FormGroup 实例提供了添加和删除窗体实例的方法,它们也允许您注册 onData 财务报告和审定财务报表 onValid 在形式组上的事件,焦点将是这两个可以被适配器使用的事件:
数据上的窗体组
窗体组 onDataSubscription 实例方法,让我们通过一个索引列表,以及每次引用任何形式实例的回调函数 onData,这对处理表格组很有用
valid 上的窗体组
窗体组 onValidSubscription 实例方法 让您通过一个索引列表, 以及每次任何形式改变其有效性状态时都会引用的回调函数, 这对于处理表格组有用, 它会返回表格组有效性状态和每个个体形式有效性状态, 每次改变表格有效性状态时都会被触发