ToolJet Show Modal 动作详解:事件触发、RunJS 调用与底层实现原理
2026/9/12 11:07:45 网站建设 项目流程

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-modalrun-queryset-variableshow-alert等并列存在于 actions 目录 中。

从源码角度看,ToolJet 在代码提示与动作注册表中维护了完整的动作清单,actions.js 中明确列出了showModalcloseModal

// 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 动作,操作路径如下:

  1. 在画布中选择一个组件(例如Button);
  2. 在右侧检查器(Inspector)中找到Events区域,为某个事件(如On click)添加一个事件处理器;
  3. 将处理器的动作(Action)选择为Show modal
  4. Modal下拉选项中,选择要显示的模态框组件(应用中必须先放置一个 Modal 组件,例如modal1);
  5. 如需要延迟执行,在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 中更推荐使用带awaitcomponents.*写法,以便在模态框状态变化完成后继续后续逻辑。

四、底层实现原理: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 } ); } },

从源码中可以提炼出几个关键实现事实:

  1. 参数解析modal参数既可以传 Modal 组件的 id 字符串,也可以传包含id字段的对象(modal?.id ?? modal做了兼容处理)。如果最终拿不到modalId,会抛出'No modal is associated with this event.'错误——这正是事件面板中未关联任何模态框时会出现的情况。
  2. open/close 分派:同一个函数同时服务于 Show modal 与 Close modal 两个动作,通过布尔参数show决定调用exposedValue.open()还是exposedValue.close()getExposedValueOfComponent(modalId, moduleId)会从指定模块(默认'canvas')中取出 Modal 组件的暴露值对象。
  3. 错误日志:调用失败时会记录结构化错误日志,事件类型分别标记为show_modalclose_modal,可用于在构建器中定位动作执行失败的原因。
  4. 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(默认)、smalllargefx编程时对应smmdlg
Modal height模态框高度,默认400px,可用 JS 绑定动态设置,例如{{components.xyz.data.key === 'Sun' ?? '600px' : '300px'}}

5.3 事件与联动

Modal 支持On openOn 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-queryset-variableshow-alertcopy-to-clipboardgo-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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询