UNPKG

fastlion-amis

Version:

一种MIS页面生成工具

139 lines (117 loc) 4.15 kB
import {extendObject} from '../utils/helper'; import {RendererEvent} from '../utils/renderer-event'; import {evalExpression} from '../utils/tpl'; import {dataMapping} from '../utils/tpl-builtin'; // 逻辑动作类型,支持并行、排他(switch)、循环(支持continue和break) type LogicActionType = 'parallel' | 'switch' | 'loop' | 'continue' | 'break'; // 循环动作执行状态 export enum LoopStatus { NORMAL, BREAK, CONTINUE } // 监听器动作定义 export interface ListenerAction { actionType: 'broadcast' | LogicActionType | 'custom' | string; // 动作类型 逻辑动作|自定义(脚本支撑)|reload|url|ajax|dialog|drawer 其他扩充的组件动作 eventName?: string; // 事件名称,actionType: broadcast description?: string; // 事件描述,actionType: broadcast componentId?: string; // 组件ID,用于直接执行指定组件的动作 args?: any; // 参数,可以配置数据映射 preventDefault?: boolean; // 阻止原有组件的动作行为 stopPropagation?: boolean; // 阻止后续的事件处理器执行 execOn?: string; // 执行条件 script?: string; // 自定义JS,actionType: custom [propName: string]: any; // 扩展各种Action } export interface LogicAction extends ListenerAction { children?: ListenerAction[]; // 子动作 } export interface ListenerContext { [propName: string]: any; } // Action 基础接口 export interface Action { // 运行这个 Action,每个类型的 Action 都只有一个实例,run 函数是个可重入的函数 run: ( action: ListenerAction, renderer: ListenerContext, event: RendererEvent<any>, mergeData?: any // 有些Action内部需要通过上下文数据处理专有逻辑,这里的数据是事件数据+渲染器数据 ) => Promise<void>; } // 存储 Action 和类型的映射关系,用于后续查找 const ActionTypeMap: {[key: string]: Action} = {}; // 注册 Action export const registerAction = (type: string, action: Action) => { ActionTypeMap[type] = action; }; // 通过类型获取 Action 实例 export const getActionByType = (type: string) => { return ActionTypeMap[type]; }; export const runActions = async ( actions: ListenerAction | ListenerAction[], renderer: ListenerContext, event: any ) => { if (!Array.isArray(actions)) { actions = [actions]; } for (const actionConfig of actions) { let actionInstrance = getActionByType(actionConfig.actionType); // 如果存在指定组件ID,说明是组件专有动作 if (actionConfig.componentId) { actionInstrance = getActionByType('component'); } else if ( actionConfig.actionType === 'url' || actionConfig.actionType === 'link' || actionConfig.actionType === 'jump' ) { // 打开页面动作 actionInstrance = getActionByType('openpage'); } // 找不到就通过组件专有动作完成 if (!actionInstrance) { actionInstrance = getActionByType('component'); } // 这些节点的子节点运行逻辑由节点内部实现 await runAction(actionInstrance, actionConfig, renderer, event); if (event.stoped) { break; } } }; // 执行动作,与原有动作处理打通 export const runAction = async ( actionInstrance: Action, actionConfig: ListenerAction, renderer: ListenerContext, event: any ) => { // 用户可能,需要用到事件数据和当前域的数据,因此merge事件数据和当前渲染器数据 // 需要保持渲染器数据链完整 const mergeData = extendObject(renderer.props.data, { event }); if (actionConfig.execOn && !evalExpression(actionConfig.execOn, mergeData)) { return; } // 修正参数,处理数据映射 let args = event.data; if (actionConfig.args) { args = dataMapping(actionConfig.args, mergeData); } await actionInstrance.run( { ...actionConfig, args }, renderer, event, mergeData ); // 阻止原有动作执行 actionConfig.preventDefault && event.preventDefault(); // 阻止后续动作执行 actionConfig.stopPropagation && event.stopPropagation(); };