news 2026/9/12 1:47:25

ToolJet RunJS 查询执行 Actions 完整指南:从运行查询到文件生成与多动作编排

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ToolJet RunJS 查询执行 Actions 完整指南:从运行查询到文件生成与多动作编排

ToolJet RunJS 查询执行 Actions 完整指南:从运行查询到文件生成与多动作编排

【免费下载链接】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 应用构建器中,RunJS 查询允许你在 JavaScript 代码片段里直接调用平台内置的 Actions,从而把"查询触发、变量管理、弹窗控制、文件导出、页面跳转、消息提示"等能力统一编排进一段脚本逻辑中。本指南以 ToolJet 2.50.0-LTS 官方文档 run-action-from-runjs 为主线,逐条讲解每种 Action 的调用语法与典型示例,并结合仓库前端源码(如 eventsSlice.js)说明底层实现与边界条件。读完本文,你将能在 RunJS 查询中熟练完成查询联动、变量读写、弹窗/提示、文件生成、应用跳转以及 async-await 多动作编排等实战操作。

一、RunJS 查询与 Actions 的对应关系

ToolJet 的 App Builder 在可视化层面把交互能力抽象为一组"事件动作(Actions)",它们既可以在组件事件面板中通过表单配置,也可以在 RunJS / RunPy 查询中通过代码直接调用。在仓库中,这一组动作被统一定义在两处:

  • ActionTypes.js:事件面板里可选的 Action 列表,包含run-queryshow-alertshow-modalset-custom-variablego-to-appgenerate-file等;
  • constants/actions.js:代码编辑器提示(code hints)中暴露给用户的 Actions 函数名清单,即ACTIONS数组。

两处形成一一对应的关系:面板上配置的run-query对应代码中的actions.runQuery()set-custom-variable对应actions.setVariable()。RunJS 查询本质上就是把这段 JS 代码注入到执行上下文,从而复用同一套executeAction事件分发机制(见 eventsSlice.js)。

在编写代码时,你可以选择两种风格:

  • 全局查询对象风格:queries.<查询名>.run(),每个查询对象由 queryPanelSlice.js 动态构建;
  • actions命名空间风格:actions.runQuery('<查询名>'),直接调用事件分发。

二、运行查询(Run Query)

2.1 两种调用语法

queries.getSalesData.run() // replace getSalesData with your query name

或等价的 actions 风格:

await actions.runQuery('getSalesData') // replace getSalesData with your query name

从源码看,queries.<name>.run(params, callbackFns)内部会对params做对象校验(非对象会被归一为空对象),并按查询定义的options.parameters过滤出合法参数后调用actions.runQuery(见 queryPanelSlice.js)。而actions.runQuery(queryName, parameters, moduleId, callbackFns)会按名称在当前模块的查询列表中查找目标查询,并构造{ actionId: 'run-query', queryId, queryName, parameters, callbackFns }事件交由executeAction执行(见 eventsSlice.js)。

需要留意两个边界条件(源码中有明确处理):

  • 若查询名称不存在,会弹出Query not found错误提示;
  • 若在查询自身的代码中调用自身(queryId === query?.id),会弹出Cannot run query from itself提示,防止无限递归(见 eventsSlice.js)。

2.2 带参数运行

当目标查询定义了参数时,传入的参数会被query.options.parameters逐个过滤,只保留声明过的参数名(见 eventsSlice.js):

await actions.runQuery('getUserById', { id: components.dropdown1.selectedValue });

三、获取查询结果数据(Get Query Data)

触发查询后若想立即在 RunJS 中使用其返回结果,可在await queries.<name>.run()之后调用以下三个函数,它们由 queryPanelSlice.js 以"实时 getter"方式提供:

函数返回值对应底层字段
getData()查询处理后的数据resolvedState中该查询的data
getRawData()查询的原始响应数据该查询的rawData
getLoadingState()查询是否处于加载中该查询的isLoading
// 触发查询并读取数据 await queries.getSalesData.run(); let value = queries.getSalesData.getData();
// 触发查询并读取原始数据 await queries.getCustomerData.run(); let value = queries.getCustomerData.getRawData();
// 触发查询并读取加载状态 await queries.getTodos.run() let value = queries.getTodos.getLoadingState();

源码中注释明确说明这些 getter 是"live getter":在await queries.x.run()完成后,任何字段(dataerrorrequestresponsemetadataresponseHeaders等)都会反映本次运行的最新结果(见 queryPanelSlice.js)。因此getData()/getRawData()必须放在await ...run()之后调用,才能拿到刚运行完的数据,否则读到的是上一次(或空)的状态。

四、变量管理:设置、删除与读取

4.1 设置变量(Set Variables)

actions.setVariable('<variableName>', `<variableValue>`)

源码中setVariable(key, value)会校验 key 非空,随后构造actionId: 'set-custom-variable'事件(见 eventsSlice.js)。

4.2 删除变量(Unset Variable)

actions.unSetVariable('<variableName>')

对应事件为unset-custom-variable,key 为空时直接忽略(见 eventsSlice.js)。另外还提供了批量删除actions.unsetAllVariables(),对应unset-all-custom-variables(见 eventsSlice.js)。

4.3 读取变量(Get Variables)

设置变量后如需在同一段 RunJS 代码内立刻取回,使用getVariablegetPageVariable

// 设置并读取普通变量 actions.setVariable('mode','dark'); //replace mode with your desired variable name return actions.getVariable('mode');
// 设置并读取页面级变量 actions.setPageVariable('number',1); //replace number with your desired variable name return actions.getPageVariable('number');

页面级变量的对应实现为setPageVariable(key, value)set-page-variablegetPageVariable(key)get-page-variable(见 eventsSlice.js)。它们与普通变量的区别在于作用域:普通变量在整个应用生命周期内有效,页面变量随页面切换而隔离或清空。

五、用户会话与界面控制

5.1 登出(Logout)

actions.logout();

实现上构造actionId: 'logout'事件,最终调用logoutAction()(来自@/AppBuilder/_utils/auth)完成当前用户登出(见 eventsSlice.js)。适合在"退出登录"按钮的 onClick 事件中通过 RunJS 触发。

5.2 打开 / 关闭弹窗(Show / Close Modal)

actions.showModal('<modalName>') actions.closeModal('<modalName>')

源码中showModal(modalName)会在当前组件树中按组件名称(component.name === modalName)查找 Modal 组件的实例 id,再构造show-modal/close-modal事件(见 eventsSlice.js)。因此参数必须与画布上 Modal 组件的名称完全一致,否则找不到对应弹窗。

5.3 设置本地存储(Set Local Storage)

actions.setLocalStorage('key', 'value');

对应set-localstorage-value事件(见 eventsSlice.js)。数据写入浏览器localStorage,可在不同页面、甚至重新打开应用后读取,适合存放主题偏好、用户设置等轻量持久化数据。

5.4 复制到剪贴板(Copy to Clipboard)

actions.copyToClipboard('<contentToCopy>')

实现上构造copy-to-clipboard事件,最终调用copyToClipboard(来自@/_helpers/appUtils)执行复制(见 eventsSlice.js)。注意浏览器对剪贴板 API 的调用往往要求用户手势(如点击按钮)上下文,在 RunJS 中同步调用通常没有问题。

六、生成文件(Generate File)

6.1 语法与参数

actions.generateFile('<fileName>', '<fileType>', '<data>')
参数说明可选值/类型
fileName生成文件的名称字符串
fileType文件类型csvplaintextpdf
data写入文件的数据任意数据,可用{{ }}引用组件/查询值

源码中对三个参数做了非空校验,任一缺失都会弹出错误提示Action failed: fileName, fileType and data are required,并构造generate-file事件(见 eventsSlice.js)。

6.2 生成 CSV 文件

actions.generateFile('csvfile1', 'csv', '{{components.table1.currentPageData}}') // generate a csv file named csvfile1 with the data from the current page of table

6.3 生成文本文件

actions.generateFile('textfile1', 'plaintext', '{{JSON.stringify(components.table1.currentPageData)}}') // generate a text file named textfile1 with the data from the current page of table (stringified)

文本格式下建议先用JSON.stringify()将对象数组序列化为字符串,否则写入内容可能不符合预期。

6.4 生成 PDF 文件

actions.generateFile('Pdffile1', 'pdf', '{{components.table1.currentPageData}}') // generate a text file named Pdffile1 with the data from the current page of table

文件生成的底层逻辑由@/_lib/generate-file提供(见 eventsSlice.js)。这一动作非常适合"一键导出报表/表格数据"场景,例如把表格当前页数据导出为 CSV 供下载。

七、应用间跳转(Go to App)

actions.goToApp('slug', queryparams)

两个参数的含义:

  • slug:目标应用的 slug。可以在已发布应用的 URL 中application/之后找到,也可以在 App Builder 右上角点击Share按钮弹出的分享弹窗中获取;
  • queryparams:以二维数组形式提供的查询参数,格式为[ ['key1','value1' ], ['key2','value2'] ]
actions.goToApp('sales-dashboard', [['period', '2026-Q3'], ['region', 'APAC']]);

实现上构造actionId: 'go-to-app'事件并携带slugqueryParams(见 eventsSlice.js)。在事件面板中,该动作对应go-to-app(见 ActionTypes.js)。目标应用收到参数后可通过globals.urlparams读取。

八、消息提示(Show Alert)

actions.showAlert('<alert type>' , '<message>' )

可用提示类型:infosuccesswarningdanger

示例:

actions.showAlert('error' , 'This is an error' )

对应show-alert事件,参数为alertTypemessage(见 eventsSlice.js)。提示会以顶部/角落的 Toast 形式展示,适合在分支逻辑中给出成功或失败反馈。注意官方示例中使用了'error',而标准可选值集合为info/success/warning/danger,实际使用建议从标准集合中选取以保证样式符合预期。

九、组合使用:async-await 编排多个动作

在 RunJS 查询中运行多个动作时,必须使用async-await来保证顺序执行,否则后续动作会在前序查询尚未完成时就启动。

典型示例:按 5 秒间隔轮询两个查询,并在每次完成后弹出信息提示:

actions.setVariable('interval',setInterval(countdown, 5000)); async function countdown(){ await queries.restapi1.run() await queries.restapi2.run() await actions.showAlert('info','This is an information') }

这里的setInterval每 5 秒调用一次countdownawait确保restapi1restapi2→ 提示按顺序完成。如果你需要更精细的"定时/间隔运行查询"能力,可进一步参考仓库中的完整指南 run-query-at-specified-intervals。

十、补充:更多可用动作与排查建议

除了文档列出的动作,ACTIONS常量(见 constants/actions.js)中还暴露了以下能力,可在 RunJS 中按同样风格调用:

函数作用
actions.resetQuery('<查询名>')重置查询状态(对应reset-query
actions.abortQuery('<查询名>')中止正在运行的查询(对应abort-query
actions.switchPage('<页面名>')切换当前应用页面
actions.logInfo(...)/actions.logError(...)向调试器输出日志
actions.toggleAppMode('<模式>')切换应用的编辑/查看模式
actions.scrollComponentInToView(...)将组件滚动到可视区域

排查建议:

  1. 查询名写错runQuery找不到查询时会提示Query not found,请核对查询面板中的名称(区分大小写);
  2. 自调用:不要在 RunJS 查询里运行它自己,否则提示Cannot run query from itself
  3. Modal 名称不匹配showModal/closeModal按组件名称精确匹配,请确认传入的名称与画布组件名一致;
  4. 数据时序getData()等读取函数必须在await ...run()之后调用;
  5. 代码提示:编辑器内输入actions.queries.时会基于ACTIONS常量与查询对象实时给出函数提示,可减少拼写错误(见 codeHinterSlice.js)。

相关文档

  • 官方指南原文:run-action-from-runjs
  • Actions 列表定义:ActionTypes.js
  • Actions 代码提示常量:constants/actions.js
  • Actions 核心实现:eventsSlice.js
  • 查询对象(run/getData/getRawData/getloadingState)实现:queryPanelSlice.js

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 1:46:47

合并报表技术演进:从Excel到AI的智能化实践

1. 合并报表编制的技术演进与现状合并报表作为企业集团财务报告的核心组成部分&#xff0c;其编制技术已经从传统手工操作发展到如今的智能化阶段。记得我刚入行时&#xff0c;财务团队每到季末都要通宵达旦地手工核对关联交易、调整抵消分录&#xff0c;而现在通过技术手段已经…

作者头像 李华
网站建设 2026/9/12 1:44:22

FlatBuffers .NET 测试指南:在 Linux 上运行与清理 NetTest 测试套件

FlatBuffers .NET 测试指南&#xff1a;在 Linux 上运行与清理 NetTest 测试套件 【免费下载链接】flatbuffers FlatBuffers: Memory Efficient Serialization Library 项目地址: https://gitcode.com/GitHub_Trending/fl/flatbuffers 导读 本文以 FlatBuffers 仓库中的…

作者头像 李华
网站建设 2026/9/12 1:44:14

Java流程控制语句详解:从原理到性能优化

1. 流程控制语句&#xff1a;程序逻辑的骨架与脉络第一次接触Java的新手常会困惑&#xff1a;为什么同样的几行代码&#xff0c;在不同条件下能产生完全不同的结果&#xff1f;答案就藏在流程控制语句里。作为从C语言继承而来的核心语法结构&#xff0c;流程控制决定了代码的执…

作者头像 李华
网站建设 2026/9/12 1:41:33

asdf 安装前置依赖指南:git 与基础工具的检查、安装与验证

asdf 安装前置依赖指南&#xff1a;git 与基础工具的检查、安装与验证 【免费下载链接】asdf Extendable version manager with support for Ruby, Node.js, Elixir, Erlang & more 项目地址: https://gitcode.com/GitHub_Trending/as/asdf asdf 是一个可扩展的版本…

作者头像 李华
网站建设 2026/9/12 1:39:36

OPPO到realme手机数据迁移全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华