ToolJet Show Modal 动作详解:事件触发、RunJS 调用与底层实现原理
【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 🚀项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet
本文围绕 ToolJet(3.0.0-LTS 版本)动作参考文档中的Show modal(显示模态框)动作展开,介绍如何在组件事件处理器中配置该动作、利用 Debounce 字段控制延迟执行,以及如何通过 RunJS 查询中的actions.showModal()以编程方式唤起模态框。结合前端源码中事件执行器的真实实现,你可以完全掌握在 ToolJet 应用构建器中以「事件 → 动作」或「代码 → 动作」两种方式控制 Modal 组件显示的方法。
一、Show modal 动作是什么
在 ToolJet 应用构建器中,几乎所有组件(按钮、表格、文本等)都支持配置事件处理器(Event Handler)。每个事件可以挂载一个或多个动作(Action),而Show modal就是动作集合中的一员,它的作用是:在事件触发时,弹出(显示)当前应用中指定的 Modal 组件。
官方动作参考文档(show-modal.md)对其的定义只有一句话:"Use this action to show the modal for an event."——即"使用该动作来为某个事件显示模态框"。它是 ToolJet 内置的 16 个标准动作之一,与close-modal、run-query、set-variable、show-alert等并列存在于 actions 目录 中。
从源码角度看,ToolJet 在代码提示与动作注册表中维护了完整的动作清单,actions.js 中明确列出了showModal与closeModal:
// frontend/src/AppBuilder/_stores/constants/actions.js export const ACTIONS = [ 'runQuery', 'resetQuery', 'setVariable', // 'setVariables', 'unsetAllVariables', 'unSetVariable', 'showAlert', 'logout', 'showModal', 'closeModal', // ... ];这意味着该动作不仅在事件面板中可选,也是 RunJS 代码环境中受官方认可的actions.*调用方法之一。
二、在事件处理器中配置 Show modal
2.1 基本配置步骤
要在事件处理器中使用 Show modal 动作,操作路径如下:
- 在画布中选择一个组件(例如Button);
- 在右侧检查器(Inspector)中找到Events区域,为某个事件(如
On click)添加一个事件处理器; - 将处理器的动作(Action)选择为Show modal;
- 在Modal下拉选项中,选择要显示的模态框组件(应用中必须先放置一个 Modal 组件,例如
modal1); - 如需要延迟执行,在Debounce字段中填写毫秒数。
下图展示了在事件处理器中选择 Show modal 动作并关联模态框的界面(截图来自官方文档 showmodal2.png):
2.2 Debounce 字段:毫秒级延迟执行
Debounce(防抖)字段是 Show modal 动作的一个关键参数,官方文档的说明为:
Debounce field is empty by default, you can enter a numerical value to specify the time in milliseconds after which the action will be performed. ex:
300
即:
- 默认值为空,表示事件触发后立即执行该动作,不做任何延迟;
- 填入数值型毫秒数后,动作将在指定时间之后才执行,例如
300表示延迟 300 毫秒后再弹出模态框; - 该字段适用于所有事件动作,通常用于在事件触发与模态框显示之间留出缓冲,例如先等待某个查询完成、或避免与动画/点击反馈冲突。
2.3 与 Close modal 动作配合使用
与 Show modal 成对存在的是Close modal动作(close-modal.md),其定义为"close the modal that is already shown",同样支持 Debounce 字段。典型用法是:
- 用一个按钮的
On click事件触发Show modal打开模态框; - 用模态框内部"取消"按钮的
On click事件触发Close modal关闭模态框。
Modal 组件自身还暴露了On open / On close两个事件(见 modal.md),你可以在模态框打开或关闭时继续串联其他动作(如运行查询、设置变量),形成完整的事件链。
三、从 JavaScript(RunJS)中触发 Show modal
除了在事件面板中静态配置,ToolJet 还支持在 JavaScript 代码中动态触发动作。官方 RunJS 指南(run-action-from-runjs.md)给出了明确的语法:
actions.showModal('<modalName>')其中<modalName>是应用中 Modal 组件的名称。例如,假设画布上有一个名为modal1的模态框:
// 打开模态框 modal1 actions.showModal('modal1')与之配套的关闭语法:
actions.closeModal('<modalName>')3.1 在 RunJS 中结合其他动作使用
RunJS 查询支持async/await,因此可以把 Show modal 与其他动作编排进同一个流程。例如先运行查询、再弹出模态框展示结果:
await queries.getUserData.run(); actions.showModal('userModal');如果需要在延时后弹出,还可以结合setTimeout或封装为异步函数:
async function openWithDelay() { await new Promise((resolve) => setTimeout(resolve, 300)); actions.showModal('modal1'); } openWithDelay();关于"在指定时间间隔内运行多个动作"的完整示例(setInterval配合actions.showAlert等),可参考 run-query-at-specified-intervals 相关章节 中的多动作编排代码。
3.2 组件专属动作(CSA):components.modal1.open()
除了actions.showModal()这一全局动作外,Modal 组件还提供了组件专属动作(Component Specific Actions, CSA),可直接通过components对象调用:
| 动作 | 说明 | 调用方式 |
|---|---|---|
open | 打开 Modal 组件 | await components.modal1.open() |
close | 关闭 Modal 组件 | await components.modal1.close() |
两者的区别在于:actions.showModal('modal1')走的是全局事件动作分发器;而components.modal1.open()直接操作组件暴露的 API,二者最终都会调用模态框暴露值的open()/close()方法(见下文源码分析)。在 RunJS 中更推荐使用带await的components.*写法,以便在模态框状态变化完成后继续后续逻辑。
四、底层实现原理:eventsSlice 中的 showModal
Show modal 动作的前端核心实现在事件分发器 eventsSlice.js 中:
showModal: (modal, show, eventObj, moduleId = 'canvas') => { try { const { getExposedValueOfComponent } = get(); const modalId = modal?.id ?? modal; if (_.isEmpty(modalId)) { throw new Error('No modal is associated with this event.'); } const exposedValue = getExposedValueOfComponent(modalId, moduleId); show ? exposedValue.open() : exposedValue.close(); return Promise.resolve(); } catch (error) { get().eventsSlice.logError( show ? 'show_modal' : 'close_modal', show ? 'show-modal' : 'close_modal', error, eventObj, { eventId: eventObj.eventType } ); } },从源码中可以提炼出几个关键实现事实:
- 参数解析:
modal参数既可以传 Modal 组件的 id 字符串,也可以传包含id字段的对象(modal?.id ?? modal做了兼容处理)。如果最终拿不到modalId,会抛出'No modal is associated with this event.'错误——这正是事件面板中未关联任何模态框时会出现的情况。 - open/close 分派:同一个函数同时服务于 Show modal 与 Close modal 两个动作,通过布尔参数
show决定调用exposedValue.open()还是exposedValue.close()。getExposedValueOfComponent(modalId, moduleId)会从指定模块(默认'canvas')中取出 Modal 组件的暴露值对象。 - 错误日志:调用失败时会记录结构化错误日志,事件类型分别标记为
show_modal与close_modal,可用于在构建器中定位动作执行失败的原因。 - Promise 化:动作执行后返回
Promise.resolve(),因此可以在 RunJS 的异步链中安全地await。
也就是说,无论是事件面板中配置的 Show modal,还是 RunJS 里的actions.showModal(),最终都汇聚到eventsSlice.showModal()这一条执行路径上,统一经过"解析模态框 id → 获取组件暴露值 → 调用 open()"的链路。
五、配套知识:Modal 组件基础
要让 Show modal 动作真正生效,应用中必须存在一个 Modal 组件。这里补充 Modal 组件文档 中的关键信息:
5.1 行为特性
Modal 组件渲染在背景遮罩(backdrop)之前,会阻塞与页面其余部分的交互,直到模态框被关闭。它适合承载对话框、灯箱(lightbox)、用户通知、表单等内容。
注意:出于避免过度复杂场景的考虑,Calendar(日历)和 Kanban(看板)两个组件被限制为不能拖拽放入 Modal 内部,否则构建器会提示<Restricted component> cannot be used as a child component within the Modal.
5.2 常用属性一览
| 属性 | 说明 |
|---|---|
| Title | 显示在模态框头部标题栏的标题。 |
| Loading state | 在模态框内容上显示加载动画,常与查询的isLoading属性绑定;可通过开关或fx绑定{{true}}/{{false}}。 |
| Hide title bar | 隐藏模态框的标题栏,可fx编程设置。 |
| Hide close button | 隐藏模态框内的关闭按钮,可fx编程设置。 |
| Close on escape key | 按 Esc 键关闭模态框,默认开启,可fx编程设置。 |
| Close on outside click | 点击模态框外部区域时关闭,可fx编程设置。 |
| Modal size | 模态框尺寸:medium(默认)、small、large;fx编程时对应sm、md、lg。 |
| Modal height | 模态框高度,默认400px,可用 JS 绑定动态设置,例如{{components.xyz.data.key === 'Sun' ?? '600px' : '300px'}}。 |
5.3 事件与联动
Modal 支持On open与On close两个事件,且与普通组件一样可以挂载多个事件处理器。常见的联动模式是:
- 表格行操作 → Show modal:点击表格某行的"编辑"按钮,触发 Show modal 打开编辑表单模态框,同时通过 RunJS/查询把当前行数据写入模态框内的表单字段;
- 模态框按钮 → 关闭 + 提交:模态框内"确认"按钮同时触发
run-query(提交数据)与closeModal(或components.modal1.close()); - 表单校验 → 延迟弹出:利用 Show modal 的 Debounce 字段,在表单校验通过后延迟 300ms 再弹出结果提示模态框。
六、小结
- Show modal是 ToolJet 内置动作,用于在组件事件触发时显示指定的 Modal 组件,配合Close modal动作可实现完整的模态框开合控制;
- Debounce 字段默认留空即立即执行,填入毫秒数值(如
300)可实现延迟弹出; - 通过 RunJS 可用
actions.showModal('<modalName>')/actions.closeModal('<modalName>')编程触发,也可用组件专属动作await components.modal1.open()/await components.modal1.close(); - 源码层面,所有路径统一汇聚到 eventsSlice.js 的
showModal()方法,经由"组件 id 解析 → 暴露值获取 →open()/close()调用"的链路执行,并内置了缺失模态框的错误提示与结构化日志。
如需查阅完整的动作清单,可继续浏览 actions 动作参考目录,其中包含run-query、set-variable、show-alert、copy-to-clipboard、go-to-app等全部标准动作的说明。
【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 🚀项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考