ToolJet Set Page Variable 动作详解:页面级变量的创建、访问与 RunJS 调用
2026/9/10 4:11:51 网站建设 项目流程

ToolJet Set Page Variable 动作详解:页面级变量的创建、访问与 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

页面变量(Page Variable)是 ToolJet 多页面应用(Multipage Apps)中作用域限定在单个页面内的动态数据载体,与贯穿整个应用的普通变量(App 级变量)不同,它只能在被创建的页面中被访问。本篇指南基于 set-page-var.md 展开,结合 ToolJet 前端源码,完整讲解 Set Page Variable 动作的配置方式、Debounce 延迟执行、通过 RunJS 查询调用该动作的语法,以及页面变量在底层状态树中的存储与求值原理。读完本篇,你将能够在多页面应用中熟练创建、读写页面级变量,并将其接入事件处理器或 JavaScript 代码。

页面变量与普通变量的区别

在 ToolJet 中,普通变量(通过 Set Variable 动作创建)属于整个应用,可以在任意页面、任意组件中通过{{variables.<key>}}访问;而页面变量则被限制在创建它的那一个页面内:

  • 作用域:仅限当前页面,无法像普通变量那样在整个应用中跨页访问;
  • 适用场景:多页面应用(Multipage Apps)中,需要为每个页面维护彼此独立的临时状态,例如分页器当前页码、筛选条件、表单暂存值等;
  • 访问方式:页面变量的值通过{{page.variables.<pageVariableName>}}动态获取,其中<pageVariableName>是使用 Set Page Variable 动作创建的具体变量名。

补充:从 pages.md 的 Exposed variables 一节可知,每个页面本身暴露了handle(页面 slug)、name(页面名称)、id(页面唯一标识)和variables(该页面通过 Set Page Variable 创建的全部变量对象)四个内置变量,page.variables即对应最后一个。

在事件处理器中配置 Set Page Variable

Set Page Variable 是一个动作(Action),可以附加到任何组件的任意事件上,最常见的场景是配合按钮的 On Click 事件或页面的 On Page Load 事件(见 pages.md)。

配置时只需要两个字段:

字段说明
Key页面变量名,即存储到page.variables对象中的键
Value要赋给该变量的值

对应的事件管理器表单实现在 EventManager.jsx:当event.actionId === 'set-page-variable'时,渲染一个 Key 字段和一个 Value 字段,两者都是CodeHinter类型的输入框,意味着 Key 和 Value 都可以直接书写表达式(例如引用其他组件的值{{components.textinput1.value}}),并支持自动补全提示。

在事件处理器中为 Set Page Variable 动作填写 Key 与 Value 字段。

Debounce:延迟执行毫秒数

默认情况下,Debounce字段保持为空,即动作立即执行。你也可以输入一个数值,表示在执行动作前等待的毫秒数,例如输入300表示延迟 300 毫秒后再设置变量。

Debounce 的典型用途是在需要节流/防抖的场景下使用,例如输入框内容变化事件中,避免每次按键都立即更新变量,从而减少不必要的状态刷新与下游重算。由于页面变量写入后会触发依赖该变量的组件重新求值(详见下文"源码中的实现"),合理使用 Debounce 可以显著降低高频事件下的渲染开销。

通过 RunJS 查询设置页面变量

除了在事件处理器中可视化配置,Set Page Variable 动作还可以在RunJS 查询中通过 JavaScript 代码直接触发,语法如下:

await actions.setPageVariable('<variablekey>', <variablevalue>);

参数规则:

  • variablekey必须作为字符串提供(用引号包裹),例如'filterKeyword'
  • variablevalue如果是数值则无需加引号,例如await actions.setPageVariable('currentPage', 3);如果是字符串或对象、数组等复合类型,则需要按 JS 语法书写(字符串加引号,对象/数组直接写字面量)。

在 RunJS 查询中使用actions.setPageVariable以编程方式写入页面变量。

示例:在 RunJS 中同时写入一个字符串变量与一个数值变量

await actions.setPageVariable('filterKeyword', 'ToolJet'); await actions.setPageVariable('currentPage', 1);

关于如何在 RunJS 查询中运行各类动作的完整说明,请参考指南 run-action-from-runjs.md。

源码中的实现:从事件到状态树

为了理解页面变量的真实行为,可以深入前端状态管理层查看实现。ToolJet 前端使用 Zustand 管理应用构建器状态,页面变量最终存储在模块(module)级的状态树中。

动作分发入口

在 eventsSlice.js 中,事件处理器按actionId分发动作:

case 'set-page-variable': { const { setPageVariable } = get(); const key = getResolvedValue(event.key, customVariables, moduleId); const value = getResolvedValue(event.value, customVariables, moduleId); setPageVariable(key, value, moduleId); return Promise.resolve(); }

可以看到,事件配置里的keyvalue会先经过getResolvedValue求值(将其中嵌入的{{...}}表达式解析为真实值),再写入页面变量存储。此外还有配套的get-page-variableunset-page-variableunset-all-page-variables三个动作分支,分别对应读取、删除单个、清空全部页面变量。

状态树的写入与依赖刷新

实际写入逻辑位于 resolvedSlice.js:

setPageVariable: (key, value, moduleId = 'canvas') => { set((state) => { state.resolvedStore.modules[moduleId].exposedValues.page.variables[key] = value; }, false, 'setPageVariable'); get().updateDependencyValues(`page.variables.${key}`, moduleId); get().rebuildVariableHints(moduleId); },

从源码结构看,可以确认以下几点实现事实:

  1. 存储位置:页面变量存放在resolvedStore.modules[moduleId].exposedValues.page.variables,与普通变量exposedValues.variables分属不同的命名空间,这正是两者作用域隔离的底层原因;
  2. 依赖联动:写入变量后立即调用updateDependencyValues('page.variables.<key>'),所有在表达式中引用了{{page.variables.<key>}}的组件会被重新求值,实现响应式更新;
  3. 编辑提示rebuildVariableHints会重建代码提示索引,使新创建的页面变量立即出现在后续表达式的自动补全候选中。

RunJS 中的 actions 对象

在 eventsSlice.js 中,暴露给 RunJS 的actions.setPageVariable被定义为:

const setPageVariable = (key = '', value = '') => { const event = { actionId: 'set-page-variable', key, value }; return executeAction(event, mode, {}, moduleId); };

它本质上就是把调用参数包装成与事件处理器相同的actionId: 'set-page-variable'事件对象,再走统一的executeAction执行通道,因此与可视化配置的事件行为完全一致——这也解释了为什么文档中 RunJS 与事件处理器两种方式可以等价互换。

动作清单与代码分析

  • 动作白名单定义在 actions.js,其中包含setPageVariableunsetPageVariableunsetAllPageVariables三项页面变量相关动作;
  • 在 scriptAnalysis.ts 中,setPageVariableunsetPageVariable被归类为pageVariableWrites(页面变量写操作),用于静态分析 RunJS 脚本对页面变量的写入依赖,进而驱动依赖图与提示系统。

实践:一个完整的多页面示例

假设一个包含"列表页"和"详情页"的多页面应用,希望在点击列表中的某一行时,把选中的记录 ID 存入当前页面的变量中:

  1. 在列表页选中一个按钮或行点击事件,添加事件处理器;
  2. 动作选择Set Page Variable
  3. Key 填selectedRecordId,Value 填{{components.table1.selectedRow.id}}(或直接写数值/字符串);
  4. 如需要延迟执行,在 Debounce 中填入毫秒数(如300)。

之后在列表页任意组件的属性或查询参数中,即可通过{{page.variables.selectedRecordId}}读取该值;由于作用域限制,切换到详情页后该变量不再可用——此时应改用应用级变量{{variables.selectedRecordId}},或通过 Switch Page 动作携带参数传值。

若希望以脚本方式实现,可在 RunJS 查询中写入:

await actions.setPageVariable('selectedRecordId', components.table1.selectedRow.id); return page.variables.selectedRecordId;

需要清理页面状态时,还可以使用配套的Unset Page Variable(删除单个变量)动作,RunJS 对应语法为await actions.unsetPageVariable('<key>');清空全部页面变量则对应unsetAllPageVariables

小结

Set Page Variable 是 ToolJet 多页面应用中实现"页面级隔离状态"的核心动作:通过事件处理器或 RunJS 两种方式均可创建页面变量,配合 Debounce 字段可控制延迟执行,写入后的变量以{{page.variables.<key>}}形式被同页组件消费。其底层实现(resolvedSlice.js 与 eventsSlice.js)展示了动作分发、表达式求值、依赖刷新与代码提示的完整链路,为理解 ToolJet 响应式状态系统提供了一个清晰的切入点。

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

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

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

立即咨询