ToolJet 跨应用导航动作完全指南:Go to app 的配置、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
导读
"Go to app"(跳转到应用)是 ToolJet 内置的一种导航类动作,用于在事件触发时打开当前工作区中任意已发布(Released)的 ToolJet 应用,是实现多应用间相互跳转、入口聚合与流程串联的核心手段。本文将从动作的触发场景、配置面板各字段、通过 RunJS 以代码方式调用,到其在 frontend 中的事件执行源码,给出完整且可验证的实战说明。读完本文,你将掌握如何在事件处理器中正确配置跳转目标与查询参数、如何获取并校验应用 slug,以及跨应用跳转在编辑器与查看器两种模式下的实际行为差异。
何时使用 "Go to app" 动作
ToolJet 应用由组件、查询与事件处理器(Event Handler)组成。每个组件都可以绑定交互事件,而每个事件又可以挂载一个或多个动作。当应用体系拆分为多个应用时(例如一个仪表盘应用 + 若干业务处理应用),"Go to app" 就是连接它们的桥梁:
- 从列表应用跳转到某个记录的详情应用,并通过查询参数传递记录 ID;
- 在一个"总入口"应用中放置多个导航按钮,分别进入不同的已发布应用;
- 在事件驱动的自动化流程中(如 RunJS 查询成功后)按条件跳转到指定应用。
正如动作定义所示,它归属于navigation(导航)分组,与 Switch page(切换页面)、Open webpage(打开网页) 同属一类,用于改变用户当前所处的位置或上下文。
使用前提:目标应用必须已发布
文档明确说明了一个约束:"Go to app" 只能打开已经发布(Released)的应用,未发布的草稿应用无法作为跳转目标。因此在实际使用前,需要:
- 在应用构建器中编辑完成应用,并通过右上角的Release(发布)按钮将其发布;
- 在另一个应用中添加 "Go to app" 动作,选择(或填写)该已发布应用的标识。
发布状态决定了该应用是否拥有可访问的线上 slug——这是动作执行时构造跳转 URL 的依据。
如何获取应用的 slug
"Go to app" 需要一个slug来唯一定位目标应用。根据官方动作文档,slug 可以通过以下两种途径获得:
- 从已发布应用的浏览器 URL 中提取:格式为
https://<your-tooljet-host>/applications/<slug>,即application/之后的路径段; - 从共享(Share)弹窗中查看:在应用构建器右上角点击Share按钮,弹出的共享弹窗中会给出该应用的发布链接,slug 即链接中的标识部分。
注意:在较新的版本中,图形化配置面板保存的是应用的稳定关联 ID(correlationId)并据此反查 slug;而通过 RunJS 直接调用时,则仍以 slug 为直接参数(详见下文)。
在事件处理器中配置 "Go to app"
添加动作并选择目标应用
在任意组件的事件处理器中新增一个动作,从动作列表选择Go to app后,会渲染对应的配置面板。该面板的实现位于 GotoApp.jsx,包含两个配置区域:
App(目标应用选择)通过下拉框(
OptionCombobox)列出当前工作区中可选的应用,选中后写入事件配置。源码注释表明新版面板持久化的是correlationId而非旧的slug字段,同时会把所选应用的slug与currentVersionId镜像到 store 的linkedApps映射中,目的是"无需刷新即可在点击时构造 URL",并让校验逻辑能够区分"目标缺失"与"没有已发布版本"两种错误。若所选应用在加载的链接映射中无法通过校验,面板会显示红色错误标签与Undefined app提示。Query params(查询参数)以"键 / 值"成对的行来维护跳转时携带的查询参数,每行是一个 CodeHinter 代码输入框(
event-query-param-key与event-query-param-value),因此键与值都可以使用动态引用(如{{components.table1.selectedRow.id}})。通过Add param按钮可追加新的键值行,行尾的删除按钮可移除不再需要的参数。
对应动作在配置层(事件模型)中的定义位于 ActionTypes.js:
{ name: 'Go to app', id: 'go-to-app', options: [ { name: 'app', type: 'text', default: '' }, { name: 'queryParams', type: 'code', default: '[]' }, ], group: 'navigation', }即:动作需要app(目标应用)与queryParams(查询参数,JSON 数组形式,默认空数组[])两类配置。
下图展示了该动作在事件处理器中的配置界面:
Debounce 防抖字段
在事件处理器中,每个动作都可以附带一个Debounce(防抖)字段:
- 默认情况下该字段为空,表示动作被触发后立即执行;
- 可以输入一个**数值(毫秒)**来指定动作延迟执行的时间,例如
300表示事件触发后 300 毫秒才执行该动作。
该字段在 EventManager.jsx 中有相应的处理逻辑:当 debounce 参数被置为空字符串时,会从事件配置中删除该键,从而恢复"立即执行"的语义。防抖非常适合与查询、按钮快速连点等高频事件配合,避免在极短时间内重复触发跳转。
通过 RunJS 以代码方式触发跳转
除了在事件处理器中图形化配置,"Go to app" 同样可以从JavaScript 代码中触发(在 RunJS 查询、组件代码等场景)。ToolJet 为各动作提供了一套全局actionsAPI,具体语法可参考 Run actions from RunJS query,其核心调用形式为:
actions.goToApp('slug', queryparams)参数说明:
slug:目标已发布应用的 slug,可从发布后 URL 的application/之后获取,或从 Share 弹窗中查看;queryparams:二维数组形式,例如[ ['key1','value1'], ['key2','value2'] ]。
一个实际示例——从当前应用跳转到 slug 为customer-detail的应用并携带客户 ID:
const row = components.table1.selectedRow; actions.goToApp('customer-detail', [['id', row.id], ['source', 'dashboard']]);在执行层,RunJS 发起的调用会被识别为event.source === 'app-action',此时直接使用传入的slug(源码注释明确说明这是为了向后兼容保留的直接传 slug 方式)。因此,代码方式跳转时 slug 是必填参数,若为空会抛出No application slug provided错误。
动作执行原理与源码级解析
"Go to app" 的核心执行逻辑位于事件运行时 eventsSlice.js,一次跳转的执行过程可以拆解为以下几步:
解析目标 slug
- 来自 RunJS(
source === 'app-action')时:直接校验event.slug非空,并通过getResolvedValue解析其中可能存在的动态引用; - 来自构建器事件配置时:要求
event.correlationId非空,然后从 store 的linkedApps(Map<correlationId, { slug, currentVersionId }>,定义于 appSlice.js)中反查该应用对应的 slug。若在编辑器模式下校验失败(应用缺失或未发布),会抛出带具体原因的异常并进入调试器错误日志(logError('go_to_app', ...));而在查看器(viewer)模式下则跳过校验直接尝试重定向,交由既有的 404/"not found" 兜底处理。
- 来自 RunJS(
组装查询参数将配置中的键值对数组
reduce成一个对象,键与值都经过getResolvedValue解析,因此可引用组件状态、变量等动态数据;随后通过serializeNestedObjectToQueryParams序列化(支持嵌套对象的展开),最终拼接出查询串。构造跳转 URL 并执行基础路径为
/applications/<slug>,若存在查询参数则追加?...;若 ToolJet 部署在子路径(subpath)下,还会自动加上子路径前缀。之后按运行模式分流:- 查看器模式(view):通过
window.open(url, '_self')在当前标签页完成跳转; - 编辑器模式(editor):会先弹出确认框
The app will be opened in a new tab as the action is triggered from the editor.,确认后基于当前 Host URL 拼出完整地址并在新标签页打开——因为编辑器本身承载着正在编辑的应用,不能直接覆盖当前页面。
- 查看器模式(view):通过
正是这条 URL 构建逻辑决定了动作"只能打开已发布应用":应用只有发布后才拥有对外可访问的 slug 路径,供拼接与访问。
此外,事件执行前的动作校验(isLinkedAppValid)及相关工具逻辑位于 AppBuilder/_stores/utils.js 附近,负责在页面/事件触发前验证 go-to-app 链接目标是否有效,从而把"配置期即可发现错误"的能力前置到构建阶段。
常见问题与注意事项
| 关注点 | 说明 |
|---|---|
| 目标应用未发布 | 跳转会失败。请先在目标应用中完成 Release,再检查其 slug 是否存在。 |
| 运行在编辑器模式下 | 跳转前会有确认弹窗,并在新标签页打开,这是为了不打断当前应用的编辑会话。 |
| 运行在已发布应用的查看模式 | 跳转发生在当前标签页(_self),体验上如同页面间的自然流转。 |
| 查询参数动态取值 | 键与值均支持模板引用({{ ... }}),可将选中行、变量等运行时数据带给目标应用。 |
| 代码方式必填 slug | 使用actions.goToApp(...)时必须传 slug,否则抛No application slug provided。 |
| 防抖配合 | 需要延迟执行时填写毫秒值;为空即立即执行。 |
从跨应用跳转这个单一动作可以看到 ToolJet 事件机制的设计取向:图形化配置(存储关联 ID、可校验、防抖可控)与代码化调用(actions全局 API)双轨并存,统一收敛到同一套事件运行时执行,既适合无代码使用者,也为开发者保留了完整的可编程空间。
延伸阅读与源码索引
- 动作官方文档(含多版本归档):docs/docs/actions/go-to-app.md(另见 version-3.0.0-LTS 与 version-2.50.0-LTS 两个版本的文档)
- 在 RunJS 中触发全部动作的 API 指南:docs/docs/how-to/run-action-from-runjs.md
- 同类导航动作:Switch page、Open webpage
- 动作配置面板源码:GotoApp.jsx
- 动作模型定义(含 options 与分组):ActionTypes.js
- 事件执行运行时(含 go-to-app 分支):eventsSlice.js
- 已链接应用映射状态:appSlice.js
- 事件配置面板与防抖处理:EventManager.jsx
【免费下载链接】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),仅供参考