关于 domo-js
面向 Domo 应用开发者的 JavaScript SDK,提供环境信息、数据访问和应用内交互工具。它还支持监听筛选器与变量变化,以及在应用中更新这些值。
主要功能
- 01读取 Domo 环境信息
- 02监听数据集更新
- 03监听筛选器和变量变化
- 04程序化更新变量与页面筛选器
- 05应用内导航及并行获取数据集
适用场景
- 01数据集更新后刷新应用数据
- 02根据页面筛选器或变量变化调整查询
- 03构建联动下拉菜单
- 04在 Domo 页面或外部链接间导航
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ stahura/ domo-ai-vibe-rules --skill domo-js安装后在 Claude Code 中输入/domo-js确认已加载。
详细介绍
domo.js (ryuu.js) SDK
安装 domo.js (ryuu.js)
React / npm 项目:
npm install ryuu.js
import domo from 'ryuu.js';
原生 JavaScript (CDN):
<script src="https://app.unpkg.com/[email protected]"></script>
domo.js 工具
除了 API 之外,domo.js 还提供了用于与 Domo 环境交互的实用工具:
环境信息
访问环境信息。警告:可能被伪造!请勿用于安全用途。
console.log(domo.env.userId); // User ID (spoofable!)
console.log(domo.env.customer); // Customer/instance name
console.log(domo.env.pageId); // Current page ID
console.log(domo.env.locale); // Locale (e.g., 'en-US')
console.log(domo.env.platform); // 'desktop' or 'mobile'
用于安全的用户验证:
// ✅ SECURE - Server-verified identity
const verifiedEnv = await domo.get('/domo/environment/v1/');
const { userId, userName, userEmail } = verifiedEnv;
// Or use IdentityClient from toolkit
import { IdentityClient } from '@domoinc/toolkit';
const response = await IdentityClient.get();
const user = response.body; // { id, displayName, emailAddress, role }
事件监听器
数据集更新
domo.onDataUpdated((alias) => {
console.log(`Dataset ${alias} was updated`);
// Refresh your data or do nothing to prevent auto-reload
});
页面筛选器变更(onFiltersUpdated / onFiltersUpdate)
当同一 App Studio 页面(或仪表板)上的原生筛选器卡片发生变化时触发。请在顶层注册——位于任何 React 组件或 useEffect 之外。
在较新的 ryuu.js 版本上可用时请使用 onFiltersUpdate,并为兼容性回退到 onFiltersUpdated。
const registerFilterListener = (handler) => {
try {
if (typeof domo.onFiltersUpdate === "function") return domo.onFiltersUpdate(handler);
if (typeof domo.onFiltersUpdated === "function") return domo.onFiltersUpdated(handler);
} catch (_) {
// Listener registry can be uninitialized in some runtimes.
}
};
registerFilterListener((filters) => {
if (!Array.isArray(filters) || filters.length === 0) return;
filters.forEach(({ column, operand, values, dataType }) => {
switch (column?.toUpperCase()) {
case "YEAR_OF_EVENT":
if (operand === "BETWEEN" && values?.length === 2) {
state.yearRange = { min: Number(values[0]), max: Number(values[1]) };
} else if (operand === "IN" && values.length > 0) {
const nums = values.map(Number).sort((a, b) => a - b);
state.yearRange = { min: nums[0], max: nums[nums.length - 1] };
}
break;
case "CATEGORY":
if (operand === "IN") {
state.categories = values.length > 0 ? values : ["ALL"];
}
break;
}
});
fetchData(); // Refetch immediately — no "apply" step for page filters
});
筛选器对象结构 —— filters 数组中的每个元素:
| 字段 | 类型 | 取值 |
|---|---|---|
column | string | 数据集列名 |
operand | string | BETWEEN、IN、GREATER_THAN_EQUAL、LESS_THAN_EQUAL、EQUALS |
values | array | 对于 BETWEEN:[min, max]。对于 IN:选中的值。对于标量:[value]。 |
dataType | string | LONG、STRING、DATE 等。 |
该字段是 operand,而不是 operator。 传入的筛选器使用 operand。传出的筛选器(通过 requestFiltersUpdate)使用 operator。这种不对称是 Domo API 中已知的不一致。
变量变更(onVariablesUpdated)
当 App Studio 变量控件发生变化时触发。变量由数字字符串 ID 标识。请在顶层注册。
domo.onVariablesUpdated((variables) => {
if (!variables || typeof variables !== "object") return;
const typeVar = variables["860"];
if (typeVar?.parsedExpression?.value) {
const label = typeVar.parsedExpression.value; // display label, e.g., "Cumulative"
state.pendingType = MY_LABEL_MAP[label]; // map to internal value
}
updateUI(); // Show pending state, don't refetch yet — wait for Apply
});
变量对象结构 —— variables 以数字函数 ID 字符串为键:
{
"858": { "parsedExpression": { "exprType": "LITERAL", "value": "Year Sold" } },
"860": { "parsedExpression": { "exprType": "LITERAL", "value": "Cumulative" } }
}
变量提供的是显示标签,需要映射到内部值。请使用待处理/提交模式:变更时存入暂存状态,仅当用户点击 Apply 时才提交并重新获取。
以编程方式更新变量(requestVariablesUpdate)
在自定义应用内写入 App Studio 变量。主要用途:级联下拉菜单——当变量 A 变化时,设置变量 B。
domo.requestVariablesUpdate(
[{ functionId: 873, value: "Initial Service" }],
(ack) => { console.log("acknowledged"); },
(reply) => { console.log("completed"); }
);
防止循环:更新变量会再次触发 onVariablesUpdated。请使用标志进行防护:
state.isUpdatingVariable = true;
domo.requestVariablesUpdate(updates, onAck, (reply) => {
state.isUpdatingVariable = false;
});
// In onVariablesUpdated: if (state.isUpdatingVariable) return;
载荷使用 functionId(数字),而不是字符串。回调为 onAck(已排队)和 onReply(已完成)。
导航
重要: 带 href 的标准锚点标签在 Domo 应用中无法正常工作。你必须使用 domo.navigate():
// Navigate within Domo
domo.navigate('/page/123456789');
// Open in new tab
domo.navigate('/page/123456789', true);
// External URLs also work
domo.navigate('https://example.com', true);
获取多个数据集
// Load multiple datasets in parallel
const [sales, customers, products] = await domo.getAll([
'/data/v1/sales',
'/data/v1/customers',
'/data/v1/products'
]);
以编程方式更新页面筛选器
domo.requestFiltersUpdate(
[
{
column: 'category',
operator: 'IN',
values: ['Electronics', 'Clothing'],
dataType: 'STRING'
}
],
true, // apply to page
() => console.log('Filter update acknowledged'),
(response) => console.log('Filter update completed:', response)
);