NocoBase FlowEngine 事件流(Event Flow)全解析:静态流、动态流与联动规则的事件驱动编排

发布时间:2026/9/15 13:39:56
NocoBase FlowEngine 事件流(Event Flow)全解析:静态流、动态流与联动规则的事件驱动编排 NocoBase FlowEngine 事件流Event Flow全解析静态流、动态流与联动规则的事件驱动编排【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase在 NocoBase 2.0 的 FlowEngine 中界面的所有组件都是**事件驱动Event-driven**的组件的行为、交互和数据变化都由事件Event触发并通过流Flow按 Step 依次执行。本文将基于 FlowEngine 的官方文档与源码实现系统讲解事件流的两大形态静态流 / 动态流、联动规则与动态流的异同、FlowAction 的复用机制、FlowModel 的四层概念模型并结合dispatchEvent、applyFlow等底层调用链帮助你从原理到实战完整掌握 FlowEngine 的事件流编排能力。一、先理解事件流的基本模型在 FlowEngine 中Flow 是服务于 Model 的逻辑流它将属性变化或事件响应逻辑拆解成有序的步骤Step按流的方式依次执行详见 什么是 FlowEngine。组件承载交互的界面单元Model组件的逻辑抽象管理属性与状态、定义渲染方式、承载并执行 Flow、统一处理事件分发与生命周期Flow逻辑流本身管理属性变化、响应事件让逻辑变得动态化、可配置化、可复用Step流中的一个执行节点每个 Step 承担一个小任务如设置属性、触发事件、调用接口流按既定顺序依次经过所有 Step并且可以分叉与组合。一句话概括组件是水车Model 是水车的底座和控制器Flow 是推动水车转动的流水Step 是水流途经的节点。事件流正是水流的源头——事件决定了水流何时启动。二、静态流与动态流类级模板 vs 实例级个性化事件流在 FlowEngine 中分为两种形态见 事件流官方文档形态定义位置生效范围典型用途静态流Static Flow由开发者在代码中定义作用于某个 Model 类的所有实例处理某个 Model 类的通用逻辑动态流Dynamic Flow由用户在界面上配置只对某个具体实例生效特定场景的个性化行为静态流是定义在类上的逻辑模板动态流是定义在实例上的个性化逻辑。从源码看这两种流在运行时分属两套注册表静态流挂在类上由GlobalFlowRegistry管理见 GlobalFlowRegistry.ts动态流挂在实例上由InstanceFlowRegistry管理见 InstanceFlowRegistry.ts。FlowModel.getFlows()负责将两者合并为一个有序的 Flow 集合合并规则清晰地体现了二者的优先级关系见 flowModel.tsx分别获取实例流与静态流跳过与实例流同名的静态流即同名时实例流覆盖静态流实例流按sort升序排序相同sort保持注册顺序稳定排序静态流已在GlobalFlowRegistry中按sort与继承深度排序合并结果动态流实例优先于静态流。三、联动规则 vs 动态流同源同机制的两种配置形态在 FlowEngine 的配置体系中实现事件逻辑有两条路径1. 联动规则Linkage Rules是内置的事件流 Step 封装配置更简单、语义化更强本质上仍然是事件流Flow的一种简化形式联动规则 ≈ 简化版事件流。2. 动态流Dynamic Flow完整的 Flow 配置能力可自定义触发器on——定义何时触发可自定义执行步骤steps——定义执行的逻辑适用于更复杂、灵活的业务逻辑。源码层面ActionScene枚举见 types.ts同时收录了联动规则与动态事件流的场景直接印证了两者共用同一套机制export enum ActionScene { BLOCK_LINKAGE_RULES 1, // 块级联动规则 FIELD_LINKAGE_RULES, // 表单字段级联动规则 SUB_FORM_FIELD_LINKAGE_RULES, // 子表单字段级联动规则 DETAILS_FIELD_LINKAGE_RULES, // 详情字段级联动规则 ACTION_LINKAGE_RULES, // 按钮级联动规则 DYNAMIC_EVENT_FLOW, // 动态事件流 MENU_LINKAGE_RULES, // 菜单项联动规则 TAB_LINKAGE_RULES, // 标签页联动规则 }可以发现联动规则按作用粒度区块、字段、子表单、详情字段、按钮、菜单项、标签页被拆分成了多个场景而动态事件流作为一个独立场景与它们并列。这从实现层面说明联动规则只是预置好 Step、面向特定 UI 场景的事件流封装动态流则是不限定场景的完整事件流能力。四、FlowAction 的一致性联动规则与事件流共用一套动作体系无论联动规则还是事件流都使用相同的 FlowAction 集合。FlowAction 定义了可被 Flow 调用的操作二者共用一套动作体系而不是分别实现两套从而确保逻辑复用、扩展一致。在源码中这一设计体现为EventDefinition与ActionDefinition的类型同构见 types.tsexport type EventDefinition TModel extends FlowModel FlowModel, TCtx extends FlowContext FlowContext, ActionDefinitionTModel, TCtx;也就是说EventDefinition 实际上是 ActionDefinition 的别名事件处理逻辑与动作执行逻辑拥有完全相同的属性结构name、title、handler、uiSchema、defaultParams、beforeParamsSave、afterParamsSave、uiMode、scene、sort等。在FlowEngine中动作与事件也采用对称的注册与查询 API见 flowEngine.tsregisterActions(actions)/getAction(name)/getActions()由EngineActionRegistry支撑的全局动作注册表registerEvents(events)/getEvent(name)/getEvents()由EngineEventRegistry支撑的全局事件注册表。动作注册表按层级分为EngineActionRegistry引擎级/全局与ModelActionRegistry模型类级FlowModel解析动作时先查模型级注册表再回退到引擎级见 flowModel.tsx。事件注册表同理其基类要求每个事件必须声明name重复注册会给出覆盖警告见 BaseEventRegistry.tsregisterEvent(def: EventDefinitionTModel): void { if (!def?.name) throw new Error(Event must have a name.); if (this.events.has(def.name)) { console.warn(Event ${def.name} is already registered. It will be overwritten.); } this.events.set(def.name, def); this.onEventRegistered(); }五、概念层级FlowModel 的四层抽象从概念上FlowModel 的核心抽象关系如下见 事件流官方文档FlowModel └── FlowDefinition ├── FlowEventDefinition │ ├── 全局事件Global Events │ └── 局部事件Local Events └── FlowActionDefinition ├── 全局操作Global Actions └── 局部操作Local Actions各层含义FlowModel一个可配置、可执行流逻辑的模型实体。它是组件逻辑的大脑负责承载 Flow、分发事件、管理生命周期FlowDefinition定义一组完整的流逻辑包含触发条件与执行步骤是流的骨架。其完整字段key、title、manual、sort、on、steps、defaultParams详见 FlowDefinition 流定义FlowEventDefinition定义流的触发源。包括全局事件如应用启动、数据加载完成与局部事件如字段变化、按钮点击。事件定义的类型、注册方式与内置事件列表详见 EventDefinition 事件定义FlowActionDefinition定义流可执行的动作。包括全局操作如刷新页面、全局通知与局部操作如修改字段值、切换组件状态。动作定义的类型、注册方式与完整示例详见 ActionDefinition 动作定义。四个定义类型Model / Flow / Event / Action / Step的逐一拆解可继续阅读 definitions 目录 下的系列文档。六、事件流如何触发与执行dispatchEvent 调用链理解层级之后最关键的问题是事件是如何被触发、又如何驱动 Flow 执行的核心入口在FlowModel上见 flowModel.tsx。1. 触发事件dispatchEventasync dispatchEvent( eventName: string, inputArgs?: Recordstring, any, options?: { debounce?: boolean } DispatchEventOptions, ): Promiseany[]eventName要触发的事件名inputArgs传递给事件流的入参options.sequential是否顺序执行默认trueoptions.useCache是否使用缓存默认falsebeforeRender的默认值为true可覆盖options.debounce是否启用防抖开启后使用 500ms、leading 方式的 lodash debounce见 flowModel.tsx。内部通过flowEngine.executor.dispatchEvent(target, eventName, inputArgs, options)真正执行见 FlowExecutor.ts最终由FlowExecutor按序运行匹配该事件的各条 Flow。2. 手动执行某条流applyFlowasync applyFlow(flowKey: string, inputArgs?: Recordstring, any, runId?: string): PromiseanyapplyFlow不经过事件匹配直接按flowKey执行指定 Flow内部调用executor.runFlow适用于代码中精确触发某一条流的场景。3. 按事件名筛选 FlowgetEventFlowspublic getEventFlows(eventName: string): FlowDefinition[]该方法的匹配规则见 flowModel.tsx体现了事件流的一个关键约定对beforeRender事件做兼容处理除显式声明on: beforeRender的流外未声明on且manual ! true的流也会被匹配即默认在渲染前自动执行对其他事件仅匹配on与事件名一致的流字符串形式on eventName或对象形式on.eventName eventName。4. 内置事件与执行时机phaseFlowEventName收录了内置常用事件见 types.tsexport type FlowEventName | click | close | submit | reset | remove | openView | dropdownOpen | popupScroll | search | customRequest | collapseToggle | (string {}); // 允许任意自定义字符串扩展当同一个事件例如click同时存在多条流时可以用phase / flowKey / stepKey指定该流插入到内置静态流的哪个位置执行详见 FlowDefinition 流定义phase含义需要的字段beforeAllFlows默认在所有内置静态流之前执行-afterAllFlows在所有内置静态流之后执行-beforeFlow在某条内置静态流开始前执行flowKeyafterFlow在某条内置静态流结束后执行flowKeybeforeStep在某条内置静态流的某个 step 开始前执行flowKeystepKeyafterStep在某条内置静态流的某个 step 结束后执行flowKeystepKey配置示例// 1) 默认在所有内置静态流之前不需要写 phase on: { eventName: click } // 2) 在所有内置静态流之后 on: { eventName: click, phase: afterAllFlows } // 3) 在某条内置静态流开始前/结束后 on: { eventName: click, phase: beforeFlow, flowKey: buttonSettings } on: { eventName: click, phase: afterFlow, flowKey: buttonSettings } // 4) 在某条内置静态流的某个步骤开始前/结束后 on: { eventName: click, phase: beforeStep, flowKey: buttonSettings, stepKey: general } on: { eventName: click, phase: afterStep, flowKey: buttonSettings, stepKey: general }七、实战示例事件流 动态流的组合使用下面组合官方文档事件流、FlowDefinition、EventDefinition的代码骨架演示事件流的典型用法。示例 1模型级静态流类级模板class PageModel extends FlowModel {} // 注册表单提交事件 PageModel.registerEvent({ name: formSubmitEvent, title: Form Submit Event, handler: async (ctx, params) { // 事件处理逻辑验证、提交、返回结果 return { success: true, data: result }; }, defaultParams: { validation: true, preventDefault: true }, uiMode: dialog, }); // 注册静态流作用于所有 PageModel 实例 PageModel.registerFlow({ key: formSettings, title: Form settings, manual: false, sort: 0, on: formSubmitEvent, steps: { validate: { use: validateFormAction, title: Validate Form, sort: 0 }, process: { use: processFormAction, title: Process Form, sort: 1 }, save: { use: saveFormAction, title: Save Form, sort: 2 }, }, });示例 2在实例上触发事件流const engine new FlowEngine(); engine.registerModels({ PageModel }); engine.setModelRepository(new MyRepository()); const model engine.createModel({ use: PageModel, uid: page-001 }); // 触发事件所有监听 formSubmitEvent 的静态流/动态流按序执行 await model.dispatchEvent(formSubmitEvent, { formData: { title: Hello } }); // 或者精确执行某一条流 await model.applyFlow(formSettings);示例 3动态流的定位动态流由用户在界面上配置通过 FlowEngine 的设置面板、DynamicFlowsEditor等组件写入实例的flowRegistry只对当前实例生效。得益于getFlows()的合并规则用户为某个实例配置的同名动态流会覆盖类上的静态流从而实现类级通用逻辑 实例级个性化覆盖的组合。八、小结事件流核心概念一览概念作用生效范围静态流 (Static Flow)在代码中定义的流逻辑所有 Model 类的实例动态流 (Dynamic Flow)在界面上定义的流逻辑单个 FlowModel 实例FlowEvent定义触发器何时触发全局或局部FlowAction定义执行逻辑全局或局部联动规则 (Linkage Rule)简化的事件流 Step 封装区块、操作级九、延伸阅读FlowEngine 概述 与 什么是 FlowEngineFlow、Step、Model 的基础概念FlowDefinition 流定义on、steps、manual、sort、defaultParams等完整字段说明EventDefinition 事件定义事件注册、内置事件与属性详解ActionDefinition 动作定义可复用动作的定义与完整示例StepDefinition 步骤定义 与 ModelDefinition 模型定义Step 与 Model 层的类型契约源码参考types.ts全部核心类型、flowEngine.ts引擎注册表与调度、flowModel.tsxdispatchEvent/applyFlow/getFlows实现、FlowExecutor.ts事件流执行器、GlobalFlowRegistry.ts 与 InstanceFlowRegistry.ts静态流 / 动态流注册表。【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询