ToolJet Timer 组件完全指南:从属性配置到源码级运行原理
【免费下载链接】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
Timer(计时器)是 ToolJet 应用构建器中用于正向/反向计时的组件,可完成倒计时、耗时统计、事件计时等场景。本文将基于 ToolJet 官方文档,结合仓库源码与测试用例,完整讲解 Timer 组件的属性、事件、暴露变量、通用配置与样式体系,并深入剖析其setInterval计时内核与状态机实现,帮助你既能在画布上熟练使用该组件,也能理解其底层运作机制。
Timer 组件是什么
Timer 组件允许用户通过向上(Count Up)和向下(Count Down)两种方式计时,适用于设置倒计时、统计耗时或为事件计时等任务。在 ToolJet 应用构建器的组件面板中,Timer 位于Presentation(呈现)分组下,与 Text、Tags、CircularProgressBar、Timeline、Statistics 等组件并列,分组定义可参见 sectionConfig.js。
从组件注册信息看,Timer 在 Widget Manager 中的定位为 "Countdown or stopwatch"(倒计时或秒表),默认尺寸为宽 11、高 128,见 timer.js。
注意:Timer 组件属于传统(legacy)组件体系。在 componentTypes.js 的
NEW_REVAMPED_COMPONENTS列表中并不包含 Timer,因此它走的是legacyUniversalProps通用属性合并路径,具体可见 componentTypes.js。
Properties(属性)
Timer 组件提供两个核心属性,官方文档与组件配置一一对应:
| 属性 | 说明 |
|---|---|
| Default value(默认值) | 指定计时器的初始值,格式为HH.MM.SS.MS,即时.分.秒.毫秒。 |
| Timer type(计时器类型) | 指定是向上计数还是向下计数。可从下拉框选择Count Up或Count Down,也可以点击fx通过编程方式动态设置为countUp或countDown。 |
源码中的属性定义
在 timer.js 中,这两个属性的底层定义如下:
value:类型为code,显示名 "Default value",校验 schema 为字符串,默认值为00:00:00:000;type:类型为select(下拉选择),选项为{ name: 'Count up', value: 'countUp' }与{ name: 'Count down', value: 'countDown' },默认值为countUp。
值得注意的是,配置中针对不同计时类型提供了差异化默认值(见 timer.js):
countUp类型默认初始值为00:00:00:000(从零开始计时);countDown类型默认初始值为00:00:10:000(从 10 秒开始倒计时)。
默认值的解析规则
从 Timer.jsx 的源码可以看出,默认值字符串通过properties.value.split(':')按冒号切分为[HH, MM, SS, MS]四段,随后由getTimeObj(见 Timer.jsx)完成解析与合法性校验:
- hour:
isNaN(HH)时为 0,否则parseInt(HH, 10); - minute:必须满足
MM <= 59,否则为 0; - second:必须满足
SS <= 59,否则为 0; - mSecond:必须满足
MS <= 999,否则为 0。
也就是说,分钟、秒、毫秒字段如果超出合理范围,会被自动归零,这保证了非法输入不会破坏计时逻辑。
Events(事件)
Timer 组件支持 5 个事件,官方文档定义如下:
| 事件 | 说明 |
|---|---|
| On start | 每当用户点击 Start(开始)按钮时触发。 |
| On resume | 每当用户点击 Resume(继续)按钮时触发。 |
| On pause | 每当用户点击 Pause(暂停)按钮时触发。 |
| On count down finish | 每当倒计时归零时触发。 |
| On reset | 每当用户点击 Reset(重置)按钮时触发。 |
在 timer.js 的配置中,这五个事件分别对应onStart、onResume、onPause、onCountDownFinish、onReset。
事件触发的源码验证
- On start / On resume:
onStart(isResume)函数在启动计时器后调用fireEvent(isResume ? 'onResume' : 'onStart'),见 Timer.jsx; - On pause:
onPause清除计时器后调用fireEvent('onPause'),见 Timer.jsx; - On reset:
onReset恢复默认值后调用fireEvent('onReset'),见 Timer.jsx; - On count down finish:在
useEffect中监测时间状态,当倒计时四个字段全部归零时清除计时器、恢复初始状态并触发fireEvent('onCountDownFinish'),见 Timer.jsx。
事件触发后可以连接到 ToolJet 的Actions(动作)体系,例如执行查询、切换组件状态、显示告警等。关于 Action 的完整用法,请参考仓库文档 actions 目录 下的各篇说明,官方文档中亦有对应指引(见 timer.md 中对 Action Reference 的提示)。
Component Specific Actions (CSA)
Timer 组件当前没有实现任何 CSA(组件专属动作),即无法像 Button、TextInput 等组件那样通过components.timer1.<action>()的语法从外部程序化控制组件。官方文档明确说明:"There are currently no CSA implemented to regulate or control the component"。
从源码看,Timer 的对外状态控制仅通过暴露变量value实现,交互控制仍依赖用户点击画布上的 Start / Pause / Resume / Reset 按钮。如果你的业务需要程序化启停计时器,可以结合Run JS动作与事件链、或者通过其他组件联动触发相应交互来间接实现。
Exposed Variables(暴露变量)
Timer 暴露一个名为value的变量,用于在运行时动态读取当前计时值:
| 变量 | 说明 | 访问方式 |
|---|---|---|
| value | 保存计时器的当前值,包含hour、minute、second、mSecond四个键。 | 通过 JS 动态访问,例如{{components.timer1.value.second}} |
在源码中,暴露变量定义于 timer.js,初始为空字符串;组件挂载时通过setExposedVariable('value', {})建立暴露通道(见 Timer.jsx),并在每次状态变更(开始、暂停、继续、重置)时同步更新:
- 开始/继续时:
setExposedVariable('value', time)(见 Timer.jsx); - 暂停时:
setExposedVariable('value', time)(见 Timer.jsx); - 重置时:
setExposedVariable('value', getTimeObj(getDefaultValue))(见 Timer.jsx)。
实际使用示例
value对象的结构固定为{ hour, minute, second, mSecond },你可以在任何支持 JS 表达式的位置使用它,例如:
- 在 Text 组件中显示当前秒数:
{{components.timer1.value.second}} - 在按钮的禁用条件中判断是否到达指定秒数:
{{components.timer1.value.second >= 30}} - 拼接完整时间字符串:
{{components.timer1.value.hour}}h {{components.timer1.value.minute}}m {{components.timer1.value.second}}s
提示:毫秒字段的 key 为
mSecond(注意大小写),value对象中不存在单独的毫秒别名键。
General(通用设置)
Tooltip(提示信息)
Tooltip 常用于当用户将鼠标悬停在组件上时展示额外的说明信息。在General折叠面板下,你可以输入字符串类型的提示文本,设置后鼠标悬停在 Timer 组件上即会显示该文本。
Tooltip 属于组件的通用属性。从源码看,传统组件通过legacyUniversalProps.general注入tooltip字段(类型为code,字符串校验),定义见 componentTypes.js,随后通过combineProperties与组件自身的 general 配置合并(见 componentTypes.js)。
Devices(设备可见性)
Timer 组件支持按设备类型控制显示:
| 设备 | 说明 | 期望值 |
|---|---|---|
| Show on desktop | 在桌面视图中显示该组件。 | 可通过开关按钮设置,或点击fx输入逻辑表达式动态配置。 |
| Show on mobile | 在移动视图中显示该组件。 | 可通过开关按钮设置,或点击fx输入逻辑表达式动态配置。 |
源码中的默认配置为:桌面端显示({{true}})、移动端隐藏({{false}}),见 timer.js 中的others定义。
Styles(样式)
Timer 组件提供以下样式配置项:
| 属性 | 说明 | 配置方式 |
|---|---|---|
| Visibility(可见性) | 控制组件的可见性。 | 开关按钮切换,或点击fx输入逻辑表达式动态配置。 |
| Disable(禁用) | 启用或禁用组件。 | 开关按钮切换,或点击fx输入逻辑表达式动态配置。 |
| Box shadow(盒阴影) | 设置组件的盒阴影属性。 | 选择阴影颜色并调整相关属性,或通过fx编程设置。 |
源码中visibility与disabledState均定义为布尔类型的 toggle,默认值分别为true与false,见 timer.js;boxShadow则来自传统组件的generalStyles,默认值为0px 0px 0px 0px #00000040(见 componentTypes.js)。
官方文档特别提示:任何带fx按钮的属性字段都可以进行编程式配置(programmatically configured),这意味着你可以用表达式、组件引用或查询结果来动态驱动这些样式。
源码级原理:Timer 的计时内核与状态机
理解 Timer 组件的底层实现,有助于你预测它在复杂场景下的行为。核心渲染逻辑位于 Timer.jsx,关键机制如下:
1. 基于 setInterval 的 15ms 计时步长
Timer 使用setInterval以15 毫秒为步长驱动时间变化(见 Timer.jsx):
- Count Up:每 15ms 毫秒数
+15,超过 1000ms 进位到秒,秒满 60 进位到分,分满 60 进位到时; - Count Down:每 15ms 毫秒数
-15,小于 0 时向秒借位(+1000),依次向下借位,当小时也小于 0 时强制归零(MS=0, SS=0, MM=0, HH=0)。
这种"以毫秒为最小单位、逐级进位/借位"的实现方式,使得显示值始终是规整的HH:MM:SS:MS格式,而不是一个浮点秒数。
2. 四态状态机
组件内部通过state维护一个四态状态机(见 Timer.jsx):
initial(初始):显示Start按钮;running(运行中):显示Pause按钮;paused(已暂停):显示Resume按钮;- Reset按钮在任意状态下都常驻显示。
按钮渲染逻辑见 Timer.jsx,同时有两个细节值得注意:
- 倒计时归零后,Start 按钮会被自动禁用(
isStartDisabled判断,见 Timer.jsx),防止归零后继续执行无效倒计时; - 当
disabledState(禁用样式)开启时,所有按钮都会追加disabledclass。
3. 属性变更自动重置
组件监听properties.type与默认值的变化(见 Timer.jsx):一旦你在编辑器中修改了计时类型或默认值,计时器会自动清除当前计时器、恢复初始状态并重新加载新默认值。因此在运行时动态切换countUp/countDown会导致计时中断并重置,设计交互时需留意。
4. 组件卸载清理
组件通过useEffect的 cleanup 函数在卸载时清除intervalId(见 Timer.jsx),避免定时器泄漏导致的资源占用。
5. 样式实现
Timer 的显示样式定义在主题样式表 theme.scss 中:.timer-wrapper提供 10px 内边距,.counter-container以font-size: 3em居中展示大号时间数字,便于在仪表盘等场景中清晰读数。
测试验证
Cypress 端到端测试中已覆盖 Timer 组件的基础渲染验证:在 componentsBasicHappypath.skip.js 中通过verifyComponentWithOutLabel("Timer", "timer1", "timer2", data.appName)校验组件拖入画布后的默认命名规则(timer1、timer2……)与基础可用性,可作为你在自动化测试中参考的断言模式。
常见使用场景小结
结合上述能力,Timer 组件在 ToolJet 应用中的典型用法包括:
- 考试/答题倒计时:Timer type 设为
countDown,配合On count down finish事件在时间耗尽时自动提交表单或执行查询; - 任务耗时统计:Timer type 设为
countUp,通过暴露变量value在页面其他位置实时展示已用时间; - 流程步骤计时:利用
On start/On pause/On resume/On reset事件组合记录每个环节的用时,并写入数据库。
小结
本文完整覆盖了 Timer 组件的属性(默认值、计时类型)、五个交互事件、暴露变量value的四个键、Tooltip 与设备可见性、三类样式配置,并深入源码剖析了其 15ms 步长的setInterval计时内核、四态状态机、属性变更重置与卸载清理机制。无论你是要快速在画布上搭建一个倒计时场景,还是希望深入理解 ToolJet 传统组件的实现范式,本文均可作为直接参考。相关的完整配置与实现文件为 timer.md、timer.js(配置) 与 Timer.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),仅供参考