4. 在线编码
4.1 在线编码说明
指在线写代码,写的内容会直接运行,全局已经定义了configs的变量,所有的数据通过configs获取。
变量 | 说明 | 例子 |
---|---|---|
btnConfig | 按钮配置 | configs.btnConfig |
context | 表单上下文 | configs.context |
data | 表单数据 | configs.data |
relation | 联动,可以增加、触发联动 | configs.relation |
utils | 工具类,可以弹窗,加载组件等 | configs.utils |
通用参数解释
变量 | 说明 |
---|---|
formCode | 组件的formCode , |
attrCode | 组件的code, |
4.1.1 context 上下文
变量 | 说明 | 入参 | 例子 |
---|---|---|---|
addListener | 添加监听方法,主要是事件执行前触发,事件执行后触发以及值改变时触发 | { code: 唯一值即可; type: 'valueChange' | 'beforeEvent' | 'afterEvent' ; handler: 回调方法 } |
configs.context.addListener({ code: ‘test’, type: ‘valueChange’,handler: ({ configs, extra, value }) => {} }) |
config | 整体表单配置 | configs.context.config | |
dictionary | 表单数据字典,不包含明细表 | configs.context.dictionary | |
form | 表单,可用于校验值和获取值,具体参考antd form的api | configs.context.form.getFieldValue() | |
getBtnConfig | 获取按钮配置 | { formCode: 空字符串,attrCode:按钮所在容器的attrCode,btnCode:按钮的code } | configs.context.getBtnConfig({ formCode: ‘parentCode’, attrCode: ‘attrCode’, btnCode: ‘save’ }) |
getCompParams | 获取由上下文传给组件的配置 | { formCode: 组件的formCode,attrCode:组件的attrCode } | configs.context.getCompParams({ formCode: ‘parentCode’, attrCode: ‘attrCode’}) |
getCompRef | 获取组件对应api,比如获取明细表的数据字典,返回组件api,组件都有onChange的api | { formCode: 组件的formCode,attrCode:组件的attrCode } | configs.context.getCompRef({ formCode: ‘parentCode’, attrCode: ‘attrCode’}).getDictionary() |
getConfig | 获取组件配置,返回IConfig类型 | { formCode: 组件的formCode,attrCode:组件的attrCode } | configs.context.getConfig({ formCode: ‘parentCode’, attrCode: ‘attrCode’}) |
getDictionary | 获取数据字典 | configs.context.getDictionary() | |
getFormData | 获取表单数据 | configs.context.getFormData() | |
getFormId | 获取表单id,如果创建则返回空 | configs.context.getFormId() | |
refresh | 刷新数据 | configs.context.refresh() | |
refreshBtnConfigs | 刷新按钮配置 | { formCode: 空字符串,attrCode:按钮所在容器的attrCode } | configs.context.refresh({ formCode: ‘parentCode’, attrCode: ‘attrCode’}) |
refreshConfigs | 刷新配置 | isDeep: 是否深度刷新,true的话比较整个配置会重新刷新 | configs.context.refreshConfigs(true) |
reset | 编辑状态刷新为创建 | configs.context.reset() | |
setBaseConfig | 设置组件的基础配置,比如是否展示,是否编辑等,设置后需要调用refreshConfigs | configs.context.setBaseConfig({formCode:’’,attrCode:’’, attr: ‘改变属性的key’, value: ‘改变属性的value’, extra: ‘如果是明细的话,对单行操作则需要填对应信息{ id:’’ }’}) | |
setCompParams | 设置需要传给组件的参数 | { ‘对应组件的code’:{} } | configs.context.setCompParams({ test: { onSearch: () => false } }) |
setFormData | 设置表单内容,该方法改变值后不会触发联动,需要触发联动则需用getCompRef获取组件api,然后调用onChange,如:configs.context.getCompRef({formCode:’’,attrCode:’’}).onChange(1) | configs.context.setFormData({a:12,b:21}) | |
setRuleConfig | 设置组件校验规则,比如必填等,设置后需要调用refreshConfigs | configs.context.setRuleConfig({formCode:’’,attrCode:’’, attr: ‘改变属性的key’, value: ‘改变属性的value’, extra: ‘如果是明细的话,对单行操作则需要填对应信息{ id:’’ }’}) | |
unlisten | 注销监听 | { code: 监听的值; type: ‘valueChange’ | ‘beforeEvent’ | ‘afterEvent’; } | configs.context.unlisten({ code:’’, type: ‘valueChange’}) |
4.1.2 data 数据
变量 | 说明 | 例子 |
---|---|---|
allData | 表单上所有数据 | configs.data.allData |
currentData | 当前容器数据,比如执行在card上,就只拿到card里面的内容 | configs.data.currentData |
preData | 同一事件里,上一环节执行事件结果,比如事件中会拿到前置事件的结果,后置事件会拿到事件中的结果 | configs.data.preData |
extraData | 额外的数据,如果是明细表的操作按钮,可以获取到选中结果,如果是明细表的行按钮,可以获取到行数据,具体可以打印 | configs.data.extraData |
4.1.3 relation 联动
变量 | 说明 | 入参 | 例子 | |
---|---|---|---|---|
on | 注册联动 | {attrCode: 组件attrCode, formCode: 组件formCode, actionCode: 执行类型,类型有:blur(失焦执行)、focus(聚焦执行)、change(值改变执行)、search(搜索时执行)、create(打开创建时执行)、edit(打开编辑时执行)、destroyOnCreate(创建表单结束离开时执行)、destroyOnEdit(编辑表单结束离开时执行},{id:场景下唯一值, cb: 联动回调} | configs.relation.on({attrCode:’’,formCode:’’,actionCode:’change’},{id: ‘唯一值,避免重复’, cb: (ctx) => {}}) | |
emit | 执行联动 | {attrCode: 组件attrCode, formCode: 组件formCode, actionCode: 与on的actionCode相同},{attrCode: ‘可选’,formCode:’可选’,index:’明细表需要的序号’,id:’明细表需要的id’} | configs.relation.emit({attrCode:’’,formCode:’’,actionCode:’change’}, {}) |
4.1.4 utils 工具类
变量 | 说明 | 例子 |
---|---|---|
confirm | 参考antd confirm用法 | configs.utils.confirm({ title: ‘title’, content: ‘content’, onOk: () => {} }) |
notification | 参考antd notification用法 | configs.utils.notification.warning({ message: ‘warning’, description: ‘warning’ }) |
message | 参考antd message用法 | configs.utils.message.warning(‘message’) |
useCompModal | 入参:Content:组件, modalConfigs:modal配置,参考antd Modal,contentConfig:组件配置 | configs.utils.useCompModal(Component, { title: ‘弹窗标题’}, {a: ‘组件入参1’, b: ‘组件入参2’}) |
loadCmp | 拉取资源组件,入参:{sourceName: 资源名称,exposesKey:导出的资源} | configs.utils.loadCmp({ sourceName:’lcp-page-component’, exposesKey: ‘charts’ }) |
fetch | 调用接口,入参参考axios | configs.utils.fetch({ url:’/apis/common/proxy/lcpGw/tz_api/服务编码/path路径’,method: ‘get’ ,params: {a:123}}) |
cache | 缓存,可以获取以及存缓存,api有:setValue,getValue,clear;缓存实际挂载在window的天舟云缓存空间中 | configs.utils.cache.setValue(‘key’, 123),configs.utils.cache.getValue(‘key’),configs.utils.cache.clear(‘key’) |
4.1.5 extra 联动额外数据
变量 | 说明 | 例子 |
---|---|---|
attrCode | 当前触发的字段的code | |
formCode | 当前触发的字段的formCode | |
id | 如果在明细行行中,存在id | |
index | 如果在明细行中,存在行下标,一般是数字,如果是树形明细表,下标是字符串 | 如果是1,表示第二行,如果是”1-2”,表示第1行的的第二个子行 |
4.2 示例
当请求成功后,我们希望按钮可以弹出对应提示信息,我们可以通过后置事件,配置在线编码
const preData = configs.data.preData;
if(preData.status!=="0"){
configs.utils.notification.error({message:preData.message,content:preData.message});
}else{
configs.utils.notification.success({message:"更新成功",content:"更新成功"});
}
const pageId = configs.context.globalContext.pageTools.getDetailPageId(configs.context.config);
configs.context.globalContext.pageTools.refresh(pageId);
获取元素/组件的值
方法一
const formData = configs.context.getFormData();
const aValue = formData?.['a'];
方法二
const aValue = configs.data.allData?.['a'];
设置元素/组件的值
仅改变值
configs.context.setFormData({ a: 123 });
configs.relation.emit({ attrCode: 'a', formCode: 'formCode', actionCode: 'change' }, { id: '如果是明细表,需要明细表行id', index: 0 });
仅改变值后会自动触发联动的做法
// 明细表的formCode一般是没有,所以formCode填空字符串
const aRef = configs.context.getCompRef({ formCode: `123`, attrCode: '12' });
aRef.onChange(123);
设置元素/组件可编辑状态
正常元素/组件
// 1 表示可编辑,0 表示不可编辑
configs.context.setBaseConfig({ formCode: `123`, attrCode: '12', attr: 'isEditable', value: '1' });
configs.context.refreshConfigs(true);
如果是明细表,需要加上id和index
configs.context.setBaseConfig({ formCode: `111`, attrCode: '12', attr: 'isEditable', value: '1', extra: { id: '123', index: 1} });
configs.context.refreshConfigs(true);
设置元素校验规则
// attr 有 | 'required' 'max' 'min' 'maxLength' 'minLength' 'len' 'special' 'compare' 'pattern' 'accuracy'
// 开启必填
configs.context.setRuleConfig({ formCode: '', attrCode: '', attr: 'required', value: '1', extra: { id: '如果是针对明细表某一行,需要写id,如果是主表对明细表操作,不写', index: '如果是针对明细表某一行,需要写index,如果是主表对明细表操作,不写' } })
设置元素/组件禁用状态
正常元素/组件
// 1 表示可用,0 表示禁用
configs.context.setBaseConfig({ formCode: `123`, attrCode: '12', attr: 'isEnabled', value: '1' });
configs.context.refreshConfigs(true);
如果是明细表,需要加上id和index
configs.context.setBaseConfig({ formCode: `111`, attrCode: '12', attr: 'isEnabled', value: '1', extra: { id: '123', index: 1} });
configs.context.refreshConfigs(true);
设置元素/组件隐藏显示状态
正常元素/组件
// 1 表示显示,0 表示隐藏
configs.context.setBaseConfig({ formCode: `123`, attrCode: '12', attr: 'isVisible', value: '1' });
configs.context.refreshConfigs(true);
如果是明细表,需要加上id和index
configs.context.setBaseConfig({ formCode: `111`, attrCode: '12', attr: 'isVisible', value: '1', extra: { id: '123', index: 1} });
configs.context.refreshConfigs(true);
设置按钮禁用状态
// formCode填按钮所在容器的formCode,attrCode填容器的code,btnCode填按钮的code,比如按钮所在容器是在card里面,点击设计器的card后,在设计配置可以看到对应的code,鼠标放上去可以看到对应的formCode。2.4版本后formCode可以在高级属性->表单组编码看到,如果没有,则填空字符串
// 如果是表单属性配置的表单按钮,formCode填空字符串,attrCode填'BTN_BLOCK_GLOBAL';
const btnConfig = configs.context.getBtnConfig({ formCode: ``, attrCode: '容器的code', btnCode: '123'});
if (!btnConfig.config.uiConfig) {
btnConfig.config.uiConfig = {}
}
if (!btnConfig.config.uiConfig.attr) {
btnConfig.config.uiConfig.attr = {}
}
// true 表示禁用,false 表示可用
btnConfig.config.uiConfig.attr.disabled = true;
configs.context.refreshBtnConfigs({ formCode: ``, attrCode: '12' });
设置按钮隐藏
// formCode填按钮所在容器的formCode,attrCode填容器的code,btnCode填按钮的code,比如按钮所在容器是在card里面,点击设计器的card后,在设计配置可以看到对应的code,鼠标放上去可以看到对应的formCode。2.4版本后formCode可以在高级属性->表单组编码看到,如果没有,则填空字符串
// 如果是表单属性配置的表单按钮,formCode填空字符串,attrCode填'BTN_BLOCK_GLOBAL';
const btnConfig = configs.context.getBtnConfig({ formCode: ``, attrCode: '容器的code', btnCode: '123'});
// 1 表示显示,0 表示隐藏
btnConfig.config.baseConfig.isVisible = '1';
configs.context.refreshBtnConfigs({ formCode: ``, attrCode: '12' });
明细表
- 明细表是表单的一种元素,数据格式是数组,每一行数组都是一个对象,每一组对象都有ID的key,如果是新增一行数据,在当行数据需要加__add: true。
- 如果是个树形的明细表,每一行的数据中都有children的key,children表示是子行,值是一个数组,数据格式明细表一样。
- 如果有子行或者行数据中有children字段,说明是树形明细表。
新增一行数据,利用context.getCompRef的能力实现新增一行并可以执行联动明细表新增一行
const { context, data } = configs; const tableRef = context.getCompRef({ formCode: 'formCode', attrCode: 'attrCode' }); let tableData = data?.allData?.['tableAttrCode']; if (!Array.isArray(tableData)) { tableData = []; } const id = +new Date() tableData.push({ ID: id, __add: true }); // onChange可以改变值和触发联动 tableRef?.onChange?.([...tableData], { id, formCode: 'formCode', attrCode: 'attrCode', index: tableData.length })
明细表新增一行,并在子行插入其他元素的数据
const { context, data } = configs; const tableRef = context.getCompRef({ formCode: 'formCode', attrCode: 'attrCode' }); let tableData = data?.allData?.['tableAttrCode']; let aValue = data?.allData?.['aValue']; if (!Array.isArray(tableData)) { tableData = []; } const id = +new Date() const newRow = { ID: id, __add: true, children: [] }; if (!Array.isArray(tableData)) { aValue = [] } aValue?.forEach((_a) => { newRow.children.push({ ID: Math.random(), __add: true, aValue: _a}) }) tableData.push(newRow); // onChange可以改变值和触发联动 tableRef?.onChange?.([...tableData], { id, formCode: 'formCode', attrCode: 'attrCode', index: tableData.length })
弹窗点击确定
const { context } = configs;
// 通过弹窗等待用户确认
const isConfirmed = await new Promise(rs => {
configs.utils.confirm({
title: '确认是否做什么事情',
content: '',
okText: '确认',
cancelText: '取消',
onOk: () => {
// 确认
rs(true);
},
onCancel() {
// 取消
rs(false)
}
})
});
if (isConfirmed) {
// 做一些事情
}
弹窗提示
configs.utils.message.warning('message');
获取表单数据
例子1:
const formData = configs.context.getFormData();
例子2:
// allData 是表单上所有数据
const { allData } = configs.data;
获取用户信息
const userInfo = context.getContext()?.session?.user ?? {};
// 一般有账号,邮箱,用户id,名称,电话
const { account, email, id, name, telephone } = userInfo;
校验,可阻止后续事件执行
const { context } = configs;
const formData = context.getFormData();
const a = formData?.['a'];
if (a === 1) {
// 后续事件可以拿到response内容,后续事件configs?.data的preData就是response
response = { success: true, data1: { ttt: 1111 } }
} else {
// success为false时,后续事件不继续执行
response = { success: false }
}
跳转到对应tab
// 获取tab的ref,tab是没有formCode,所以填空字符串即可
const tabRef = context.getCompRef({ formCode: '', attrCode: 'TAB_62136AC9079FC'});
// 跳转到对应tab签
tabRef?.setTabKey?.('TABPANE_9AE31CDE5A86E');
调用天舟云内置保存事件
const saveHandler = configs.utils?.cache?.getCache?.()?.['FORMREGISTER']?.["__commonSave"]?.eventHandler;
console.log('--saveHandler', saveHandler);
const currentData = configs?.context?.getFormData?.();
const resp = await saveHandler?.({
context: configs.context,
data:{
currentData,
allData: currentData,
},
btnConfig: {
scope: ['__GLOBAL_SCOPE'],
}
})
组件调用天舟云内置保存事件
import CirCache from '@cvte/cir-cache';
const Page = () => {
const cirCacheRef = useRef(new CirCache({ storage: 'memory' }));
const detailRef = useRef()
const handleSave = async () => {
const context = detailRef.current?.RenderRef?.current?.getContext() ?? {};
const saveHandler = (cirCacheRef.current?.getCache?.() as any)?.FORMREGISTER
?.__commonSave?.eventHandler;
if (!saveHandler) {
throw new Error('unexpected savehandler');
}
if (!context) {
throw new Error('unexpected context');
}
const currentData = context.getFormData?.();
const resp = await saveHandler({
context,
data: {
currentData,
allData: currentData
},
btnConfig: {
scope: ['__GLOBAL_SCOPE']
}
});
return resp;
};
return <DetailTemp ref={detailRef} {...其他参数} />
}
调用天舟云内置校验事件
const validateFn = configs.utils?.cache?.getCache?.()?.['FORMREGISTER']?.["__commonGetFormDetailData"]?.eventHandler;
// 会先校验,再返回保存的格式数据
const validatedFormData = await validateFn?.(configs);
// 如果能拿到数据,说明校验成功,如果失败,返回undefined
储存外部工具
// 系统里面储存内容
import CirCache from '@cvte/cir-cache';
const cache = new CirCache({ storage: 'memory' })
cache.setValue('your tool name', 123);
// 在线代码消费内容
const tool = configs.utils.cache.getValue('your tool name');
// tool()
调用history
// 前端2.4版本前
const { cache } = configs.utils || {};
cache.getValue('history-cache').push('/your/url');
// 前端2.4版本后内置history
const { extra } = configs.utils || {};
extra.getValue('history').push('/your/url');
调用搜索
// 说明是谁调用事件,方便排查链路
const owner = 'test';
// 获取事件总线
const subjectEventBus = configs.utils?.getSubjectEventBus?.();
// 调用搜索事件,
subjectEventBus.publishEvent({ owner, eventName: 'form:onSearch' , data: { name: '模糊查询的值,和code二选一', code: '精确查询的值,和name二选一', formCode: '目标字段的formCode', attrCode: '目标字段的attrCode', afterSearchOperate: 'firstOption或者noValue, 搜索后连接器判断noValue的话,不会执行连接器配置的联动,firstOption暂时没支持', id: '如果目标在明细表中,需要行id', index: '如果目标在明细表中,需要行序号' }});
模板调用渲染上下文
// 列表和详情调用不一样
// 详情
const context = ref.current?.RenderRef?.current?.getContext() ?? {};
// 列表
const context = ref.current?.getRef?.()?.getRenderRef?.()?.getContext?.() ?? {};
请求映射
// 表单按钮接口请求
{
// 表单数据
data: {},
// 表单配置
page: {
classId,
layout: [],
code,
id,
},
// 获取组织和用户信息
session: {
org: {
orgCode,
id,
orgName
},
user: {
account,
name,
},
},
// 获取url上的query
url: {}
// 前置事件数据
preData: {}
}
// 例子:${data.字段}:${page.id}
// 联动请求
{
response,
formData
}
// 列表
{
extraData: {
entity,
ref: {
selectedKeys,
selectedRows
}
},
page: {
layout: [],
pageCode,
id,
},
preData,
session: {
org: {
orgCode,
id,
orgName
},
user: {
account,
name,
},
url: {
}
}
}
明细表获取选择行数据
const tableRef = configs.context.getCompRef({ formCode: '', attrCode: '明细表code' });
const { selectedRows, selects } = tableRef?.getSelects?.() || {}
触发联动
configs.relation.emit({ formCode: '', attrCode: '', actionCode: 'change' })
监听联动
relation?.on?.(
{
// 监听当前设置选项映射的属性,发生选项值改变时
// 则将配置了返回字段的属性值,改为该选项中映射字段的值
actionCode: 'change',
attrCode: '', // 属性字段编码;如果是监听明细表,那么此处要写明细表编码
formCode: '', // 主表/明细表编码;如果是监听明细表,那么此处要写undefined
},
{
// 内置联动id如果每次不唯一,那么每次都会增加无效的联动
id: relationId,
cbParams: {
// 传给回调方法的参数
},
cb: async (relationCtx: IRelationClassOnConfigsFnCtx) => {
// TODO
const {
cbParams, // 传给回调方法的参数
id: relatedRowId, // 当前联动的行id
index: relatedRowIndex, // 当前联动的行索引
value: changedValue, // 当前触发联动的值内容
} = relationCtx.extra || ({} as any);
}
},
);
获取内置方法
// 前端tz-render@1.0.1.10版本后内置history,download,upload
const { extra } = configs.utils || {};
extra.getValue('history').push('/your/url');
extra.getValue('download')({ fileName: '文件名称', noTime: 是否加上时间, blob: 文件流 });
const files = await extra.getValue('upload')({ fileType: 'file', fileAccept: '.xlsx,.xls,.et' });
调用模板
const { loadCmp } = configs?.utils || {};
// 调用列表模板
const Page = loadCmp({ sourceName: 'tz-render', exposesKey: 'Page' });
// 调用表单模板
const Detail = loadCmp({ sourceName: 'tz-render', exposesKey: 'Detail' });
// 参数参考:https://docs.cvte.com/docs/tzv16/216
作者:王浩彬 创建时间:2024-06-20 09:06
最后编辑:袁子涵 更新时间:2025-05-12 18:04
最后编辑:袁子涵 更新时间:2025-05-12 18:04