news 2026/9/12 14:41:54

ToolJet RunJS(Run JavaScript Code)查询完全指南:在低代码应用中编写与执行自定义 JavaScript

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ToolJet RunJS(Run JavaScript Code)查询完全指南:在低代码应用中编写与执行自定义 JavaScript

ToolJet RunJS(Run JavaScript Code)查询完全指南:在低代码应用中编写与执行自定义 JavaScript

【免费下载链接】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

Run JavaScript Code(下称 RunJS)是 ToolJet 内置的一种查询类型,允许你在应用中直接编写并执行自定义 JavaScript 代码,用于数据转换、组件属性操控、条件逻辑判断与动作触发等场景。本文以 tooljet-concepts/run-js.md 为主体骨架,结合仓库中的数据源参考文档、多个 how-to 教程与前端源码,系统讲解 RunJS 的创建流程、参数机制、Action 调用 API、内置库与外部库导入,以及基于 Geolocation API 的完整实战案例,帮助你全面掌握这一 ToolJet 高阶能力。

什么是 RunJS 查询

Run JavaScript Code查询让开发者与业务用户无需离开 ToolJet 应用构建器,就能编写并执行自定义 JavaScript 逻辑。它的典型用途包括:

  • 转换查询返回的数据(例如格式化、聚合、过滤);
  • 读取并动态修改其他组件的属性(例如根据条件隐藏/显示组件、更新文本内容);
  • 根据特定条件触发动作(例如点击按钮后执行一串自定义逻辑);
  • 生成随机数、唯一 ID 等动态值并回填到组件中。

从源码结构看,RunJS 在 ToolJet 前端被建模为一种静态数据源(static data source)kind,定义于 frontend/src/AppBuilder/QueryManager/constants.js,其展示名称为Run JavaScript code,短名JavaScript;在查询管理器的左侧数据源列表中,它同样以runjs为标识出现在 leftSidebarConstants.js 中。前端在保存与执行时会读取 RunJS 查询的options.code字段作为脚本主体(见 scriptAnalysis.ts),并对其进行语法解析分析(依赖检测、错误标注等),从而在编辑阶段就能给出静态提示。

创建 RunJS 查询

按照>alert(parameters.newAlert)

查询触发时,浏览器/应用会弹出 Alert 显示该参数值。

示例二:用参数调用另一个查询

先创建一个名为multiply的 RunJS 查询,添加参数num1(默认值10)与num2(默认值2),代码如下:

return parameters.num1 * parameters.num2;

在画布上放置一个 Text 组件,将其文本设置为{{queries.multiply.data}}即可显示乘积结果。随后再创建名为callMultiply的查询,通过给run()传入对象覆盖参数默认值:

queries.multiply.run({num1: 20, num2: 7})

执行callMultiply后,multiply查询会以num1=20num2=7重新执行并返回140。这种"查询即函数"的模式让同一段逻辑可以被多处复用、传参,是构建复杂应用的常用手段。

与组件和事件交互

RunJS 的一大核心价值在于与组件进行动态交互。你可以给按钮挂载事件处理器(Event Handler),当它被点击时触发 RunJS 查询;也可以在 RunJS 代码中读取components.<componentName>.<property>来访问组件暴露的变量(例如components.table1.currentPageData),进而操控其他组件的属性。

关于组件暴露变量(Exposed Variables)的完整清单,可参阅 tooljet-concepts/exposed-variables.md;事件(Events)与事件处理器的概念见 tooljet-concepts/events.md;ToolJet 中可配置的全部动作(Actions)体系见 tooljet-concepts/actions.md。

高级功能与内置库

RunJS 支持一系列高级能力:设置/取消变量、打开或关闭模态框、复制内容到剪贴板、将用户登出等,这些通过特定的语法与函数完成。此外,RunJS 环境内置了三个库,可直接使用,无需额外导入:

名称说明
Moment日期与时间处理库(Moment.js)
Lodash实用工具函数库(提供mergecamelCase等)
Axios基于 Promise 的 HTTP 客户端,支持GETPOSTPUT/PATCHDELETE等请求

需要说明的是,仓库前端代码本身也大量使用 Lodash(例如 appUtils.js 中import { merge, mergeWith, camelCase } from 'lodash'),这印证了 Lodash 是 ToolJet 前端运行环境中的常用工具库。

关于 Moment、Lodash、Axios 的详细文档,可分别参考官方文档站点(本文不展开外部链接)。接下来重点演示Axios的使用方式(详见 how-to/use-axios.md)。

使用 Axios 发起 HTTP 请求

GET 请求(以 JSONPlaceholder 免费 API 为例):

var url = "https://jsonplaceholder.typicode.com/users/1"; var data = (await axios.get(url)).data; return data

代码先设置 URL 变量,再发起 GET 请求并取回响应体数据,最终通过return返回给查询结果。点击Preview即可看到 API 的响应内容。

POST 请求

var url = "https://jsonplaceholder.typicode.com/users"; var data = axios.post(url,{ id: 11, name: "Shubhendra", username: "camelcaseguy", email: "shubhendra@tooljet.com",}) return data

该 POST 请求向服务器提交用户信息,成功时服务器返回Status: 201(资源创建成功)。通过这种方式,RunJS 可以充当"无后端"场景下的 API 聚合层,把外部接口数据拉取、转换后直接喂给图表或表格组件。

从 RunJS 触发 Action:完整 API 速查

ToolJet 允许在 RunJS 查询中执行各种 Actions。以下语法与示例整理自 how-to/run-action-from-runjs.md,可作为日常开发的速查手册。

Run Query(触发查询)

两种等价写法:

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

Get Query Data(获取查询结果)

触发查询后,若想立即在 RunJS 内部使用其返回值,可用getData()getRawData()getLoadingState()

await queries.getSalesData.run(); // replace getSalesData with your query name let value = queries.getSalesData.getData();
await queries.getCustomerData.run(); //replace getCustomerData with your query name let value = queries.getCustomerData.getRawData();
await queries.getTodos.run() //replace getTodos with your query name let value = queries.getTodos.getLoadingState();

Set / Unset / Get 变量

创建变量:

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

删除变量:

actions.unSetVariable('<variableName>')

设置后立即读取全局变量与页面级变量:

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');

关于变量体系的完整概念,可参阅 tooljet-concepts/variables.md。

Logout(登出)

actions.logout();

Show / Close Modal(打开/关闭模态框)

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

Set Local Storage(写入本地存储)

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

Copy to Clipboard(复制到剪贴板)

actions.copyToClipboard('<contentToCopy>')

Generate File(生成文件)

actions.generateFile('<fileName>', '<fileType>', '<data>')

其中fileName为文件名(字符串),fileType可选csvplaintextpdfdata为写入文件的数据。实际示例:

actions.generateFile('csvfile1', 'csv', '{{components.table1.currentPageData}}') // 将表格当前页数据导出为 csvfile1.csv
actions.generateFile('textfile1', 'plaintext', '{{JSON.stringify(components.table1.currentPageData)}}') // 生成文本文件(数据经 JSON.stringify 序列化)
actions.generateFile('Pdffile1', 'pdf', '{{components.table1.currentPageData}}') // 生成 PDF 文件

Go to App(跳转其他应用)

actions.goToApp('slug',queryparams)
  • slug可以在已发布应用的 URL 中application/之后找到,也可以在应用构建器右上角点击Share弹出的分享弹窗中获取;
  • queryparams使用如下格式传入:[ ['key1','value1' ], ['key2','value2'] ]

Show Alert(显示提示)

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

可用的 alert 类型为infosuccesswarningdanger。示例:

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

一次运行多个 Action

在 RunJS 中串联多个动作时,必须使用async-await。下面示例每隔 5 秒依次执行两个查询并弹出信息提示(完整版见 how-to/run-query-at-specified-intervals.md):

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') }

上述各类 Action 的详细参考文档位于 actions 目录,例如 show-alert.md、set-variable.md、generate-file.md 等,均可在 RunJS 中按上述方式调用。

导入外部 JavaScript 库

除内置库外,RunJS 还支持通过 CDN 动态导入任意第三方 JavaScript 库(详见 how-to/import-external-lib-js.md)。推荐到 jsDelivr 查找开源项目的 CDN 链接。

导入步骤:

  1. 从 ToolJet Dashboard 新建应用;
  2. 在查询面板选择默认的JavaScript数据源创建 RunJS 查询;
  3. 在代码编辑器中粘贴以下代码(示例同时导入 MathJS 与 FlattenJS):
// Function to add script dynamically function addScript(src) { return new Promise((resolve, reject) => { const scriptTag = document.createElement('script'); scriptTag.setAttribute('src', src); scriptTag.addEventListener('load', resolve); scriptTag.addEventListener('error', reject); document.body.appendChild(scriptTag); }); } try { // Importing MathJS await addScript('https://cdn.jsdelivr.net/npm/mathjs@11.7.0'); // Importing FlattenJS await addScript('https://cdn.jsdelivr.net/npm/flattenjs@2.1.3/lib/flatten.min.js'); // Showing a success alert await actions.showAlert("success", 'Mathjs and Flatten imported'); } catch (error) { console.error(error); }
  1. 点击Run运行,应弹出 "Mathjs and Flatten imported" 成功提示。

:::tip 勾选查询设置中的Run this query on application load?选项,可在应用加载完成后立即使这些库全局可用。 :::

应用示例 1:用 FlattenJS 展平嵌套 JSON

return flatten({ key1: { keyA: 'valueI' }, key2: { keyB: 'valueII' }, key3: { a: { b: { c: 2 } } } });

应用示例 2:用 MathJS 做数学计算

return math.atan2(3, -3) / math.pi;

在查询管理器中预览输出,或在查询面板点击Run查看结果。

实战案例:用 RunJS + Geolocation API 获取用户位置

下面通过 how-to/access-users-location.md 的完整流程,演示 RunJS 与浏览器 Geolocation API 结合的真实场景(该 API 通过 GPS、Wi-Fi、IP 定位等手段提供经纬度、海拔、速度等地理数据;出于隐私考虑,浏览器会在定位前请求用户授权)。

  1. 新建一个应用;
  2. 进入应用编辑器,在底部查询面板点击+ Add,数据源选择Run JavaScript Code创建 RunJS 查询;
  3. 编写以下代码调用 Geolocation API:
function getCoordinates() { // Function to get coordinates return new Promise(function (resolve, reject) { // Promise to get coordinates navigator.geolocation.getCurrentPosition(resolve, reject); // Get current position }); } async function getAddress() { // Function to get address const position = await getCoordinates(); // Await the coordinates let latitude = position.coords.latitude; // Get latitude let longitude = position.coords.longitude; // Get longitude return [latitude, longitude]; // Return the coordinates } return await getAddress(); // Return the address
  1. 在查询编辑器下方的Settings中勾选Run this query on application load?,确保应用每次打开都自动获取位置;
  2. 点击Run,浏览器会弹出位置授权提示,允许后即可获得坐标;
  3. 查询成功后,坐标会显示在查询编辑器的Preview区;也可以在左侧边栏的Inspector中展开queries -> runjs1 -> data查看返回结果;
  4. 将坐标用于Map(地图)组件:向画布添加 Map 组件,在其Initial location属性中填入:
{{ {"lat": queries.runjs1.data[0], "lng": queries.runjs1.data[1]} }}
  1. 更新属性后,地图组件即会显示用户当前位置。

这个案例很好地展示了 RunJS 的完整链路:浏览器原生能力(Geolocation)→ RunJS 查询 → 查询结果暴露为queries.*.data→ 组件属性绑定 → 可视化呈现。

调试与错误处理

RunJS 也支持刻意制造异常以辅助调试(详见 how-to/intentionally-fail-js-query.md):

  1. 在查询面板点击+ Add新建 RunJS 查询;
  2. 在编辑器中粘贴以下代码,利用ReferenceError构造函数主动抛出错误:
throw new ReferenceError('This is a reference error.');
  1. 为该查询添加事件处理器(Event Handler),在查询**失败(failure)**时触发 Alert 等动作;
  2. 点击Run观察错误被抛出并触发失败处理逻辑。

这种"失败路径演练"可以验证应用的容错与兜底机制,提升整体健壮性。

从源码看 RunJS 的实现原理

结合前端源码,可以更深入理解 RunJS 在 ToolJet 中的实现定位:

  • 静态数据源建模runjsrunpytooljetdb同属于静态数据源(static data sources),见 QueryManagerBody.jsx;且 RunJS 查询不支持中止(abort)操作,ABORT_UNSUPPORTED_KINDS集合包含runjs(见 constants.js)。
  • 脚本静态分析:前端会对 RunJS 的options.code进行解析分析(analyzeScript),并基于options对象做 WeakMap 缓存;查询保存会替换 options,从而自动失效缓存(见 scriptAnalysis.ts)。这意味着编辑器能够在运行前就识别脚本中的依赖与潜在问题。
  • 查询面板集成:查询面板切片对runjs类型的查询有专门处理逻辑(见 queryPanelSlice.js),说明 RunJS 与查询运行状态、依赖变更检测深度绑定。

这些实现细节印证了 RunJS 并非简单的"文本执行器",而是与查询管理器、依赖分析、事件系统深度集成的第一等公民能力。

更多参考资料

  • 查询(Queries)基础概念:tooljet-concepts/queries.md
  • RunJS 查询的完整参考(参数、示例查询、内置库):data-sources/custom-js.md
  • 从 RunJS 执行动作:how-to/run-action-from-runjs.md
  • 在 RunJS 中使用 Axios:how-to/use-axios.md
  • 导入外部库:how-to/import-external-lib-js.md
  • 获取用户位置:how-to/access-users-location.md
  • 定时触发查询:how-to/run-query-at-specified-intervals.md
  • 刻意制造查询失败:how-to/intentionally-fail-js-query.md

【免费下载链接】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 14:41:26

前端工程化配置文件解析与最佳实践

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

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

空调线控器弱电接线与蓝牙调试标准化实践

1. 为什么空调线控器的弱电接线和蓝牙调试必须“标准化”——从三起现场返工说起 去年夏天在杭州一个精装交付的别墅项目里&#xff0c;我跟着施工队跑了整整两周。不是调试失败&#xff0c;而是反复返工&#xff1a;第一套客厅空调线控器装完&#xff0c;业主一按“制冷”&…

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

Java校园卡系统实战:Eclipse+Tomcat+JDBC完整开发指南

简介&#xff1a;这是一份基于Java开发的轻量级校园卡管理系统源码包&#xff0c;面向Java初学者与课程设计学生&#xff0c;聚焦校园场景下的饭卡充值、消费记录与账户管理等核心功能&#xff0c;适合作为Java SE综合实践项目或毕业设计参考。资源共30个文件&#xff0c;含7个…

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

MQTT公网安全实战:从1883明文到8883 TLS加密,用Let‘s Encrypt保护设备通信

一篇一篇写到第九篇&#xff0c;MQTT 这条线已经从“能连上”走到了“能在公网稳定跑”。前面几篇我们把 EMQX 服务端搭了起来&#xff0c;也把客户端的连接认证、Topic 设计捋了一遍&#xff0c;但一直留着一个隐患——服务端和客户端之间基本都在用 1883 端口直连&#xff0c…

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

A*算法与非线性优化融合的智能路径规划技术

1. 项目概述&#xff1a;A*与非线性优化的融合路径规划 在机器人导航、游戏AI和物流调度等领域&#xff0c;路径规划始终是核心挑战。传统A 算法虽然能保证找到最短路径&#xff0c;但在复杂环境中存在计算效率低、路径不够平滑等问题。而单纯的非线性优化方法又难以处理大规模…

作者头像 李华