UNPKG

d-render

Version:

数据渲染库 - form、table、search-form

177 lines (162 loc) 6.66 kB
// 执行器放到执行器内部 // 作用执行其 import { IAnyObject, IRenderConfigDependOn, TFormConfig, IRenderConfigDependOnEffect } from '@d-render/shared' import { IKey } from './util' type TEffectFn = ((...args: unknown[])=> unknown | Promise<unknown>) | boolean interface IPrivateParam { keys: Array<string> oldValues: Array<unknown> } type TEffect = [ TEffectFn, IPrivateParam ] export type IEffects = Array<TEffect> export type IExecutor = (values: IAnyObject, outValues: IAnyObject|undefined, effects: IEffects) => void | Promise<void> interface IGlobalParam { values: IAnyObject outValues?: IAnyObject keys: Array<IKey> oldValues: Array<unknown> executeChangeValueEffect: boolean } interface IEffectExecutorConfig { executor: IExecutor condition?: (effects: IEffects, executeChangeValueEffect: boolean) => boolean // eslint-disable-next-line @typescript-eslint/ban-types transformStrEffect?: (effectStr: string) => Function } export interface IEffectExecutorConfigs{ [propname: string]: IEffectExecutorConfig } interface IEffectConfig { [propname: string]: IEffects } interface IEffectParam { keys?: Array<string> effect?: IRenderConfigDependOn['effect'] // Record<string, Array<IFun>|IFun|boolean> | boolean oldValues?: Array<unknown> } // IEffectParam 全局模式时为空对象 type IEffectParams = Array<IEffectParam> export class EffectExecutor { config: IEffectExecutorConfigs types: Array<string> executeChangeValueEffect?: boolean values?: IAnyObject outValues?: IAnyObject effectsConfig?: IEffectConfig constructor (config: IEffectExecutorConfigs = {}) { this.config = config this.types = Object.keys(this.config) } setExecutor (type: string, executor: IExecutor) { this.config[type] = {} as IEffectExecutorConfig this.config[type].executor = executor this.types = Object.keys(this.config) } // 处理数组及字符型数据 compatibleEffect (effectConfig: IRenderConfigDependOnEffect, type: string, param: IPrivateParam|IGlobalParam) { const transformStrEffect = this.config[type].transformStrEffect const effect = transformStrEffect ? effectConfig[type] || effectConfig[`${type}Str`] : effectConfig[type] return ([] as Array<string|TEffectFn>).concat(effect as TEffectFn).map(e => { let fn: TEffectFn = e as TEffectFn // 当transformStrEffect不存在时 string无法转换为函数 if (typeof e === 'string') { if (typeof transformStrEffect === 'function') { fn = transformStrEffect(e) as TEffectFn } else { fn = () => { console.warn(`[transformStrEffect warn]: ${type}未配置字符串转函数的方法`) } } } return [fn, param] }) } getGlobalEffect (fieldConfig: TFormConfig, type: string) { return this.config[type].transformStrEffect ? (fieldConfig[type] || fieldConfig[`${type}Str`]) : fieldConfig[type] } getExecuteEffect (params: IEffectParams, fieldConfig: TFormConfig, globalParam: IGlobalParam) { console.log('params', params) const analysisEffects = this.types // 初始化 const executeObject = analysisEffects.reduce((acc: { [key: string]: Array<unknown> }, key) => { acc[key] = [] return acc }, {}) const globalEffectSign = analysisEffects.reduce((acc:{ [key: string]: boolean }, key) => { acc[key] = false return acc }, {}) // 获取到 const globalParams = params.filter(param => { return param.effect === undefined || param.effect === true }) if (globalParams.length > 0) { // 存在时从global中需要执行的effect analysisEffects.forEach(key => { if (this.getGlobalEffect(fieldConfig, key)) globalEffectSign[key] = true }) params = params.filter(param => { return !(param.effect === undefined || param.effect === true) }) } // 此时的params均为局部处理 分析effect (params as Array<Required<Omit<IEffectParam, 'effect'> & {effect: Exclude<IEffectParam['effect'], boolean | undefined>}>>).forEach(param => { const { effect, ...privateParam } = param // 入参数抛弃effect analysisEffects.forEach(key => { // resetValue 具有一定的特殊性, 其存在局部时,不需要触发global的 但是允许存在global的reset if (typeof effect[key] === 'function') { if (key !== 'resetValue') globalEffectSign[key] = true executeObject[key].push(...this.compatibleEffect(effect, key, privateParam)) } else if (effect[key] === true) { if (key !== 'resetValue') { globalEffectSign[key] = true } else { executeObject[key].push(...this.compatibleEffect(effect, key, privateParam)) } } }) }) // 此处的入参数需要再商讨 analysisEffects.forEach(key => { if (globalEffectSign[key] && this.getGlobalEffect(fieldConfig, key)) { executeObject[key].unshift(...this.compatibleEffect(fieldConfig as IRenderConfigDependOnEffect, key, globalParam)) } else { // if (!globalEffectSign[key]) console.log(`不需要${key}全局effect`) // if (!config[key]) console.log(`没有${key}全局effect`) } }) console.log('executeObject', executeObject) return executeObject as IEffectConfig } analysisEffects (effectParams: IEffectParams, config: TFormConfig, globalParam: IGlobalParam) { console.log('effectParams', effectParams) this.executeChangeValueEffect = globalParam.executeChangeValueEffect this.values = globalParam.values this.outValues = globalParam.outValues this.effectsConfig = this.getExecuteEffect(effectParams, config, globalParam) } execute (type: string, logKey: string, ...args: [effects: IEffects, executeChangeValueEffect: boolean]) { const condition = this.config[type].condition if (args[0].length > 0) { if (!condition || (condition && condition(...args))) { this.config[type].executor(this.values!, this.outValues, args[0]) console.log(`%c[d-render]%c执行%c${logKey}.${type}`, 'color: #e6a23c', 'color: normal', 'color: #67c23a') } else { console.log(`%c[d-render]%c不符合%c${logKey}.${type}%c执行条件`, 'color: #e6a23c', 'color: normal', 'color: red', 'color: normal', args[0]) } } } executeAll (logKey: string) { // 是否让xx按顺序执行 Object.keys(this.effectsConfig as IEffectConfig).forEach((type) => { this.execute(type, logKey, this.effectsConfig![type], this.executeChangeValueEffect!) }) } }