当前位置: 首页 > Web前端 > JavaScript

xflow流程可视化-可设计高级配置

时间:2023-03-27 18:20:49 JavaScript

第一部分简单介绍了formilyjs,并基于它搭建了一个表单设计器,实现了表单的动态设计和预览功能。本片将介绍窗体设计器的一些高级配置,这样可以更好的为我们的节点编辑和连接编辑工作。可设计的高级配置请求和自定义数据注入一般来说,我们页面的请求都是统一封装的。我们如何在使用时将我们打包的请求或现有的数据源注入到我们的表单设计器中?:SchemaField组件是专门用于解析JSON-Schema动态渲染表单的组件。在使用createSchemaField的时候,我们可以通过传入scope来注入全局scope链接:import{FC,Ref,useEffect,useImperativeHandle,useState}from'react';import{Modal}from'antd';import{FormItem,Input,Form,提交,ArrayBase,ArrayCards,ArrayCollapse,ArrayItems,ArrayTable,ArrayTabs,BaseItem,Cascader,Checkbox,DatePicker,Editable,FormButtonGroup,FormCollapse,FormGrid,FormTab,GridColumn,NumberPicker,Password,PreviewText,Radio,Reset,Select,SelectTable,Space,Switch,TimePicker,Transfer,TreeSelect,Upload,}from'@formily/antd';importapifrom'@/api';import{createSchemaField}from'@formily/react';import{LgetItem}from'@/utils/storage';import{createForm}from'@formily/core';interfacePreviewProps{previewRef:Ref<{setVisible:(flag:boolean)=>void}>;模态配置:{[键:string]:any};}constSchemaField=createSchemaField({组件:{Input,ArrayBase,ArrayCards,ArrayCollapse,ArrayItems,ArrayTable,ArrayTabs,BaseItem,Cascader,Checkbox,DatePicker,Editable,Form,FormButtonGroup,FormCollapse,FormGrid,FormItem,FormTab,GridColumn,NumberPicker,Password,PreviewText,Radio,Reset,Select,SelectTable,Space,Submit,Switch,TimePicker,Transfer,TreeSelect,Upload,},scope:{$fetch:api,selectList:[{标签:'aaa',value:'aaa'},{label:'bbb',value:'bbb'}]}});constPreview:FC=({previewRef,modalConfig})=>{const[可见,setVisible]=useState(false);useImperativeHandle(previewRef,()=>({setVisible,}));const[params,setParams]=useState({});constnormalForm=createForm({});useEffect(()=>{if(modalConfig&&visible){constplaygroundList=LgetItem('playgroundList')||[];constdata=playgroundList.find((s)=>s.id===modalConfig.id);setParams(数据?.params||{});}},[modalConfig,可见]);consthandleCancel=()=>{setVisible(false);};返回(Save);};exportdefaultPreview;在使用表单设计器的时候,可以使用注入的scope值,比如我们准备一个json,选择一个下拉控件,配置responder,然后通过我们注入的请求json获取这个,显示对应的下拉值:$effect(()=>{$self.loading=true$fetch({url:'/getSelectList',方法:'get',params:{}}).then(res=>{$self.loading=false//当返回值不是label和v时变换$self.dataSource=res.map(s=>({label:res.name,value:res.id}))}).catch(()=>{$self.loading=false})},[])在这里,$fetch是我们注入到请求表单中的内容。表单配置表单提交的key是一个字段标识,可以自定义修改。默认为随机字符串。form表单的label支持自定义搜索,比如select,需要在组件属性下的filter中配置form格式支持label搜索(inputValue,option)=>{returnoption.label.indexOf(inputValue)!==-1;}如果配置了responderrule,与外部配置相同,比如组件属性,那么responderrules中的外部配置将被覆盖(外部组件属性无效)。常见联动、动态值等场景讲解$self是当前选中的表单对象$form是表单对象$deps是依赖对象(需要在依赖字段上面配置source字段)$observable声明一个可观察对象$effect和react的useEffect使用类似$values对于提交的表单Form对象动态枚举值,如果我们有一个select控件,这个控件的值由接口返回$effect(()=>{$self.loading=true$fetch({url:'/getSelectList',method:'get',params:{}}).then(res=>{$self.loading=false//当返回值不是label和value时转换$self.dataSource=res.map(s=>({label:res.name,value:res.id}))}).catch(()=>{$self.loading=false})},[])联动改变枚举值,例如,我们有两个select,第一个select是一个机制组织,第一个select是用户人员,我们选择一个组织后,第二个select会从界面中获取该组织下的人员列表g到第一个select的值,这是一个比较常见的联动选择功能,那么我们如何在表单设计器中实现呢(实现方式不是唯一的,这里提供一个思路)。//在第一个select中,我们监听机制的变化。flag的主要应用是跳过初始渲染(保证反向显示的正常显示)。当机制被修改时(即手动选择值),用户的值被清除。$effect(()=>{$self.loading=true$fetch({url:'/getMechanismList',方法:'get',params:{}}).then(res=>{$self.loading=false//当返回值不是label和value时进行转换$self.dataSource=res.map(s=>({label:res.name,value:res.id}))}).catch(()=>{$self.loading=false})},[])conststate=$observable({flag:false});$effect(()=>{if(state.flag){$form.reset('user');}state.flag=true;},[$self.value])当机制改变时,清除用户列表并发起获取用户列表的请求$effect(()=>{$self.dataSource=[]if($deps.mechanism){$self.loading=true$fetch({url:'/getSelectList',method:'get',params:{mechanism:$deps.mechanism}}).then(res=>{$self.loading=false//当返回值不是label和value时转换$self.dataSource=res.map(s=>({label:res.name,value:res.id}))}).catch(()=>{$self.loading=false})}},[$deps.mechanism])我们使用模拟数据来简单地建立链接//mock/api.tsexportdefault{'GET/api/mechanism':[{value:'1',label:'Mechanism1',},{value:'2',label:'Organization2',},],'GET/api/users':(req,res)=>{//添加跨域请求头constquery:any=req.query;constuser:any={'1':[{value:'1-1',label:'机构1-人员1',},{value:'1-2',label:'机构1-人员2',},],'2':[{value:'2-1',label:'机构2-人员1',},{value:'2-2',label:'机构2-人员2',},],};res.send(用户[query.id]);},};我们定义了两个mock接口,mechanism和users,前者返回一个机构列表,后者根据前者的id返回对应的列表,然后我们在上一期的预览弹窗中注入请求,这里直接使用umi提供的request//Preview.tsximport{request}from'umi';...constSchemaField=createSchemaField({components:...,scope:{$fetch:request,},});最后我们在表单设计/机制中添加request/$effect(()=>{$self.loading=true$fetch("/api/mechanism",{}).then((res)=>{$self.loading=false//当返回值不是Convertthelabelandvalue$self.dataSource=res}).catch(()=>{$self.loading=false})},[])//users$effect(()=>{$self.dataSource=[]if($deps.mechanism){$self.loading=true$fetch("/api/users",{params:{id:$deps.mechanism,},}).then((res)=>{$self.loading=false//当返回值不是标签或值时转换$self.dataSource=res}).catch(()=>{$self.loading=false})}},[$deps.mechanism])最后我们预览一下表单模板:好了,本文介绍的功能已经实现了,那么下一篇我们将流程的编辑功能关联到我们的表单模板,修改表单模板。修改节点或链接的属性编辑,实现真正的动态属性编辑效果,期待。本文地址:链接本github地址:链接githubdemo地址:链接