跳转至

Parameters and events(参数与事件)

Parameters and events are the primary mechanisms for widgets to interact with host applications like Workshop. Parameters allow host applications to pass data into the widget, while events enable widgets to communicate back to the host application.

When developing custom widgets, you define parameters to allow users to configure widget behavior and interact with the host application, and you define events to enable two-way communication. This page explains the available parameter types, their formatting requirements, and how to use events.

:::callout{theme="neutral" title="Constraints"} Widget configuration files have a limit of 50 parameters and 50 events. Parameter and event IDs must be in camelCase format. :::

Parameters

Parameters allow widgets to share state with the host application. They can be defined as primitive types, arrays of primitive types, and object set types.

Parameter types

Type Description Format Example
boolean Boolean values (true/false) Boolean true or false
date Calendar date ISO 8601 format: YYYY-MM-DD "2023-12-31"
number Numeric values Number 42 or 3.14159
string Text values String "Hello World"
timestamp Date and time with timezone ISO 8601 format: YYYY-MM-DDThh:mm:ss.sssZ "2023-12-31T23:59:59.999Z"
objectSet Object set Object set RID ri.object-set.main.temporary-object-set.2af08bf0-3feb-416e-9e34-ad604940581b

Object set parameters allow you to pass a set of objects between a custom widget and its host application. An object set may contain zero or more objects, either as a fixed list or as a set of filters applied to an object type or interface. An object set parameter should be defined in the widget configuration file with an object type or interface from an Ontology SDK (OSDK).

Unavailable parameter types

Types such as object set filters and structs are currently unsupported as first-class parameter types for custom widgets.

Usage in parameter definitions

When defining parameters in your widget configuration file, use the appropriate type designation:

```TypeScript tab="parameter-examples.ts" { parameters: { // Primitive parameter example startDate: { type: "date", displayName: "Start Date" }, // Array parameter example tags: { type: "array", subType: "string", displayName: "Tags" }, // Object set parameter example flights: { type: "objectSet", allowedType: Flight, displayName: "Flights" } } }

## Events

Events allow widgets to communicate with the host application (such as Workshop) and trigger side effects or update parameters. Events can be defined in your widget configuration file alongside parameters.

### Defining events

Events are defined in the widget configuration file with the following structure:

```TypeScript tab="events-definition.ts"
{
  events: {
    myEventId: {
      displayName: "Human-readable event name",
      parameterUpdateIds: ["parameter1", "parameter2"],
    },
  },
}

The parameterUpdateIds field specifies which parameters can be updated when this event is triggered.

Parameter and event binding in Workshop

In Workshop, widget parameters can be bound to Workshop variables, and widget events can be bound to Workshop events in the Widget setup panel. This allows for two-way communication:

  1. Workshop can pass data to widgets through parameter bindings, and a widget can update these parameters by emitting events.
  2. Workshop events can also be bound to widget events in order to trigger side-effects in Workshop.

Examples

Below are complete examples showing both the widget configuration and usage in React.

Primitive parameters and events

First, define parameters and events in your configuration file:

```TypeScript tab="simpleCounter.config.ts" import { defineConfig } from "@osdk/widget.client";

export default defineConfig({ id: "simpleCounter", name: "Simple Counter", description: "A minimal counter example", type: "workshop", parameters: { name: { displayName: "Name", type: "string", }, count: { displayName: "Count", type: "number", }, }, events: { updateCount: { displayName: "Update Count", parameterUpdateIds: ["count"], }, }, });

Then, use these parameters and events in your widget component:

```TypeScript tab="Widget.tsx"
import { useFoundryWidgetContext } from "@osdk/widget.client-react";
import React, { useCallback } from "react";
import type SimpleCounterConfig from "./simpleCounter.config.js";

const useWidgetContext = useFoundryWidgetContext.withTypes<typeof SimpleCounterConfig>();

export const Widget = () => {
  const { parameters, emitEvent } = useWidgetContext();

  const name = parameters.values.name ?? "World";
  const count = parameters.values.count ?? 0;

  const increment = useCallback(() => {
    emitEvent("updateCount", {
      parameterUpdates: { count: count + 1 },
    });
  }, [emitEvent, count]);

  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
};

Object set parameter

First, define parameters and events in your configuration file:

```TypeScript tab="flights.config.ts" import { Flight } from "@custom-widget/sdk"; import { defineConfig } from "@osdk/widget.client";

export default defineConfig({ id: "flights", name: "Flights Example", description: "An example with flights", type: "workshop", parameters: { flights: { displayName: "Flights", allowedType: Flight, type: "objectSet", }, }, events: {}, });

When using an object set parameter, an OSDK client must be passed into the `FoundryWidget` component. To use the `useObjectSet` hook from `@osdk/react` for data fetching, you must also wrap your widget with `OsdkProvider2`. This provider enables the experimental React hooks that offer automatic caching, loading states, and real-time updates:

```TypeScript tab="main.tsx"
import { FoundryWidget } from "@osdk/widget.client-react";
import { OsdkProvider2 } from "@osdk/react/experimental";
import { createRoot } from "react-dom/client";
import FlightsConfig from "./flights.config.js";
import { client } from "./client.js";
import { Widget } from "./Widget.js";

const root = document.getElementById("root")!;

createRoot(root).render(
  <FoundryWidget config={FlightsConfig} client={client}>
    <OsdkProvider2 client={client}>
      <Widget />
    </OsdkProvider2>
  </FoundryWidget>
);

Then, use these parameters and events in your widget component. Since useObjectSet cannot be called with a null or undefined object set, the pattern below uses a separate component that only renders once the object set is available:

```TypeScript tab="Widget.tsx" import { Flight } from "@custom-widget/sdk"; import type { ObjectSet } from "@osdk/api"; import { useObjectSet } from "@osdk/react/experimental"; import { useFoundryWidgetContext } from "@osdk/widget.client-react"; import React from "react"; import type FlightsConfig from "./flights.config.js";

const useWidgetContext = useFoundryWidgetContext.withTypes();

export const Widget = () => { const { parameters } = useWidgetContext();

const flightsParam = parameters.values.flights;

if (flightsParam == null) { return

Select an object set
; }

return ; };

const FlightsView = ({ objectSet }: { objectSet: ObjectSet }) => { const { data: flights, isLoading, error } = useObjectSet(objectSet);

if (isLoading) { return

Loading flights...
; }

if (error) { return

Error loading flights
; }

return (

Flights: {flights?.map(f => ...)}

); };
The value of an object set parameter contains an object set RID as well as an instantiated OSDK object set for convenience. When the object set definition changes, or data is invalidated in the host application, the object set RID and instantiated OSDK object set in the parameter value will update.

:::callout{theme="neutral" title="Learn more about @osdk/react"}
For more information on `useObjectSet` and other React hooks for querying, actions, and caching, see the [official @osdk/react documentation ↗](https://palantir.github.io/osdk-ts/react/getting-started).
:::

### Update an object set parameter

You can update an object set parameter by emitting an event using an OSDK `ObjectSet` to update the parameter.

First, define the event in your configuration file with the object set parameter in `parameterUpdateIds`.

```TypeScript tab="flights.config.ts"
import { Flight } from "@custom-widget/sdk";
import { defineConfig } from "@osdk/widget.client";

export default defineConfig({
  id: "flights",
  name: "Flights Example",
  description: "An example with flights",
  type: "workshop",
  parameters: {
    flights: {
      displayName: "Flights",
      allowedType: Flight,
      type: "objectSet",
    },
  },
  events: {
    updateFlights: {
      displayName: "Update Flights",
      parameterUpdateIds: ["flights"],
    },
  },
});

Then, use emitEvent to update the object set parameter with a new ObjectSet.

```TypeScript tab="Widget.tsx" import { Flight } from "@custom-widget/sdk"; import { useFoundryWidgetContext } from "@osdk/widget.client-react"; import React, { useCallback } from "react"; import { client } from "./client.js"; import type FlightsConfig from "./flights.config.js";

const useWidgetContext = useFoundryWidgetContext.withTypes();

export const Widget = () => { const { parameters, emitEvent } = useWidgetContext();

const filterToLongFlights = useCallback(() => { const longFlights = client(Flight).where({ duration: { $gt: 500 }, });

emitEvent("updateFlights", {
  parameterUpdates: { flights: longFlights },
});

}, [emitEvent]);

return (

); };
:::callout{theme="note" title="Behavior and limitations"}
The SDK creates a temporary object set from your `ObjectSet` definition and sends the resulting RID to the host application. If the same event is emitted multiple times in quick succession, only the last call will be sent. Earlier calls are discarded to prevent race conditions. <br><br>
Errors during object set creation, such as network failures, are not surfaced to the caller.
:::

:::callout{theme="note" title="Refreshing object set data after actions"}
If your widget uses OSDK to apply Ontology actions that modify data in an object set parameter, you can enable automatic data refresh. See [Refresh host data on action](https://palantir.com/docs/foundry/custom-widgets/use-osdk/#refresh-host-data-on-action) for details.
:::


---

# 中文翻译

# 参数与事件

参数(Parameters)和事件(Events)是小部件与 Workshop 等宿主应用交互的主要机制。参数允许宿主应用向小部件传递数据,而事件则使小部件能够向宿主应用发送反馈。

在开发自定义小部件时,您可以定义参数来让用户配置小部件行为并与宿主应用交互,同时定义事件以实现双向通信。本页介绍了可用的参数类型、格式要求以及如何使用事件。

:::callout{theme="neutral" title="约束条件"}
小部件配置文件最多支持 50 个参数和 50 个事件。参数和事件的 ID 必须采用 `camelCase` 格式。
:::

## 参数

参数允许小部件与宿主应用共享状态。参数可以定义为原始类型(primitive types)、原始类型数组以及对象集类型(object set types)。

### 参数类型

| 类型          | 描述                 | 格式                                        | 示例                                                                              |
| ------------- | -------------------- | ------------------------------------------- | --------------------------------------------------------------------------------- |
| `boolean`     | 布尔值(true/false) | 布尔类型                                    | `true` 或 `false`                                                                 |
| `date`        | 日历日期             | ISO 8601 格式:`YYYY-MM-DD`                 | `"2023-12-31"`                                                                    |
| `number`      | 数值                 | 数字类型                                    | `42` 或 `3.14159`                                                                 |
| `string`      | 文本值               | 字符串类型                                  | `"Hello World"`                                                                   |
| `timestamp`   | 带时区的日期和时间   | ISO 8601 格式:`YYYY-MM-DDThh:mm:ss.sssZ`   | `"2023-12-31T23:59:59.999Z"`                                                      |
| `objectSet`   | 对象集               | 对象集 RID                                  | `ri.object-set.main.temporary-object-set.2af08bf0-3feb-416e-9e34-ad604940581b`    |

对象集参数允许您在自定义小部件及其宿主应用之间传递一组对象。一个对象集可以包含零个或多个对象,可以是固定列表,也可以是对某个对象类型或接口应用的一组筛选条件。对象集参数应在小部件配置文件中定义,并指定来自 Ontology SDK(OSDK)的对象类型或接口。

#### 不可用的参数类型

对象集筛选条件(object set filters)和结构体(structs)等类型目前不支持作为自定义小部件的一级参数类型。

### 在参数定义中的使用

在小部件配置文件中定义参数时,请使用适当的类型标识:

```TypeScript tab="parameter-examples.ts"
{
  parameters: {
    // 原始参数示例
    startDate: {
      type: "date",
      displayName: "开始日期"
    },
    // 数组参数示例
    tags: {
      type: "array",
      subType: "string",
      displayName: "标签"
    },
    // 对象集参数示例
    flights: {
      type: "objectSet",
      allowedType: Flight,
      displayName: "航班"
    }
  }
}

事件

事件允许小部件与宿主应用(如 Workshop)通信,触发副作用或更新参数。事件可以在小部件配置文件中与参数一起定义。

定义事件

事件在小部件配置文件中按以下结构定义:

```TypeScript tab="events-definition.ts" { events: { myEventId: { displayName: "人类可读的事件名称", parameterUpdateIds: ["parameter1", "parameter2"], }, }, }

`parameterUpdateIds` 字段指定了触发此事件时可以更新的参数。

## Workshop 中的参数与事件绑定

在 Workshop 中,小部件参数可以绑定到 Workshop 变量,小部件事件可以绑定到 Workshop 事件,这些操作可在小部件设置面板中完成。这样可以实现双向通信:

1. Workshop 可以通过参数绑定将数据传递给小部件,小部件也可以通过触发事件来更新这些参数。
2. Workshop 事件也可以绑定到小部件事件,从而在 Workshop 中触发副作用。

## 示例

以下是完整的示例,展示了小部件配置以及在 React 中的使用。

### 原始参数和事件

首先,在配置文件中定义参数和事件:

```TypeScript tab="simpleCounter.config.ts"
import { defineConfig } from "@osdk/widget.client";

export default defineConfig({
  id: "simpleCounter",
  name: "简单计数器",
  description: "一个最小化的计数器示例",
  type: "workshop",
  parameters: {
    name: {
      displayName: "名称",
      type: "string",
    },
    count: {
      displayName: "计数",
      type: "number",
    },
  },
  events: {
    updateCount: {
      displayName: "更新计数",
      parameterUpdateIds: ["count"],
    },
  },
});

然后,在小部件组件中使用这些参数和事件:

```TypeScript tab="Widget.tsx" import { useFoundryWidgetContext } from "@osdk/widget.client-react"; import React, { useCallback } from "react"; import type SimpleCounterConfig from "./simpleCounter.config.js";

const useWidgetContext = useFoundryWidgetContext.withTypes();

export const Widget = () => { const { parameters, emitEvent } = useWidgetContext();

const name = parameters.values.name ?? "World"; const count = parameters.values.count ?? 0;

const increment = useCallback(() => { emitEvent("updateCount", { parameterUpdates: { count: count + 1 }, }); }, [emitEvent, count]);

return (

你好,{name}!

计数:{count}

); };
### 对象集参数

首先,在配置文件中定义参数和事件:

```TypeScript tab="flights.config.ts"
import { Flight } from "@custom-widget/sdk";
import { defineConfig } from "@osdk/widget.client";

export default defineConfig({
  id: "flights",
  name: "航班示例",
  description: "一个关于航班的示例",
  type: "workshop",
  parameters: {
    flights: {
      displayName: "航班",
      allowedType: Flight,
      type: "objectSet",
    },
  },
  events: {},
});

使用对象集参数时,必须将 OSDK 客户端传递给 FoundryWidget 组件。要使用 @osdk/react 中的 useObjectSet 钩子进行数据获取,还需要用 OsdkProvider2 包裹小部件。该提供器支持实验性的 React 钩子,提供自动缓存、加载状态和实时更新功能:

```TypeScript tab="main.tsx" import { FoundryWidget } from "@osdk/widget.client-react"; import { OsdkProvider2 } from "@osdk/react/experimental"; import { createRoot } from "react-dom/client"; import FlightsConfig from "./flights.config.js"; import { client } from "./client.js"; import { Widget } from "./Widget.js";

const root = document.getElementById("root")!;

createRoot(root).render( );

然后,在小部件组件中使用这些参数和事件。由于 `useObjectSet` 不能接收 `null` 或 `undefined` 的对象集,下面的模式使用了一个独立的组件,该组件仅在对象集可用时才渲染:

```TypeScript tab="Widget.tsx"
import { Flight } from "@custom-widget/sdk";
import type { ObjectSet } from "@osdk/api";
import { useObjectSet } from "@osdk/react/experimental";
import { useFoundryWidgetContext } from "@osdk/widget.client-react";
import React from "react";
import type FlightsConfig from "./flights.config.js";

const useWidgetContext = useFoundryWidgetContext.withTypes<typeof FlightsConfig>();

export const Widget = () => {
  const { parameters } = useWidgetContext();

  const flightsParam = parameters.values.flights;

  if (flightsParam == null) {
    return <div>请选择一个对象集</div>;
  }

  return <FlightsView objectSet={flightsParam.objectSet} />;
};

const FlightsView = ({ objectSet }: { objectSet: ObjectSet<Flight> }) => {
  const { data: flights, isLoading, error } = useObjectSet(objectSet);

  if (isLoading) {
    return <div>正在加载航班数据...</div>;
  }

  if (error) {
    return <div>加载航班数据时出错</div>;
  }

  return (
    <div>
      <p>航班:{flights?.map(f => ...)}</p>
    </div>
  );
};

对象集参数的值包含一个对象集 RID 以及一个实例化的 OSDK 对象集,方便使用。当对象集定义发生变化或宿主应用中的数据失效时,参数值中的对象集 RID 和实例化的 OSDK 对象集将会更新。

:::callout{theme="neutral" title="了解更多关于 @osdk/react 的信息"} 有关 useObjectSet 以及其他用于查询、操作和缓存的 React 钩子的更多信息,请参阅官方 @osdk/react 文档 ↗。 :::

更新对象集参数

您可以通过触发事件并使用 OSDK 的 ObjectSet 来更新对象集参数。

首先,在配置文件中定义事件,并将对象集参数包含在 parameterUpdateIds 中。

```TypeScript tab="flights.config.ts" import { Flight } from "@custom-widget/sdk"; import { defineConfig } from "@osdk/widget.client";

export default defineConfig({ id: "flights", name: "航班示例", description: "一个关于航班的示例", type: "workshop", parameters: { flights: { displayName: "航班", allowedType: Flight, type: "objectSet", }, }, events: { updateFlights: { displayName: "更新航班", parameterUpdateIds: ["flights"], }, }, });

然后,使用 `emitEvent` 通过新的 `ObjectSet` 更新对象集参数。

```TypeScript tab="Widget.tsx"
import { Flight } from "@custom-widget/sdk";
import { useFoundryWidgetContext } from "@osdk/widget.client-react";
import React, { useCallback } from "react";
import { client } from "./client.js";
import type FlightsConfig from "./flights.config.js";

const useWidgetContext = useFoundryWidgetContext.withTypes<typeof FlightsConfig>();

export const Widget = () => {
  const { parameters, emitEvent } = useWidgetContext();

  const filterToLongFlights = useCallback(() => {
    const longFlights = client(Flight).where({
      duration: { $gt: 500 },
    });

    emitEvent("updateFlights", {
      parameterUpdates: { flights: longFlights },
    });
  }, [emitEvent]);

  return (
    <div>
      <button onClick={filterToLongFlights}>显示长途航班</button>
    </div>
  );
};

:::callout{theme="note" title="行为与限制"} SDK 会根据您的 ObjectSet 定义创建一个临时对象集,并将生成的 RID 发送给宿主应用。如果同一事件在短时间内多次触发,只有最后一次调用会被发送。之前的调用会被丢弃,以防止竞态条件。

对象集创建过程中的错误(如网络故障)不会反馈给调用方。 :::

:::callout{theme="note" title="操作后刷新对象集数据"} 如果您的小部件使用 OSDK 应用 Ontology 操作(actions)来修改对象集参数中的数据,可以启用自动数据刷新。详情请参阅操作后刷新宿主数据。 :::