> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/jia-gou/subscribe-to-changes.md).

# 订阅变更

检测组件中的变更，并在每次变更时运行函数

编写代码的一个简洁方法是订阅事件，并在事件发生时运行一个函数。

一些 [事件监听器](/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/event-listeners.md) 作为 SDK 的一部分已预先定义，但你也可以使用 `onChange()` 方法，在任何组件上都能实现相同效果。这同样适用于任何 [自定义组件](/creator/content-creator-zh/chang-jing-sdk7/jia-gou/custom-components.md) 你定义的组件，无需额外工作。

例如，下面的函数检查 `AvatarEquippedData` 玩家实体上的组件，并在玩家更换任何已装备的服饰或表情时运行一个函数。组件的新值会作为函数参数传入。

```ts
import { AvatarEquippedData } from '@dcl/sdk/ecs'

export function main() {
	AvatarEquippedData.onChange(engine.PlayerEntity, (equipped) => {
		if (!equipped) return
		console.log('新的可穿戴物品列表：', equipped.wearableUrns)
		console.log('新的表情动作列表：', equipped.emoteUrns)
	})
}
```

得益于 `onChange()` 方法，无需创建一个系统并在每一帧迭代检查新值，这大大简化了这个非常常见的用例。

{% hint style="warning" %}
**📔 注意**: 不要使用 `onChange()` 在 System 内部，因为这样会在游戏循环的每一帧都订阅一个新的函数副本，并可能导致崩溃。
{% endhint %}

同样的方法也可直接用于 [自定义组件](/creator/content-creator-zh/chang-jing-sdk7/jia-gou/custom-components.md)。例如：

```ts
// 定义组件
export const MyComponent = engine.defineComponent('myComponent', {
	value1: Schemas.Boolean,
	value2: Schemas.Float,
})

// 用法
export function main() {
	// 创建实体
	const myEntity = engine.addEntity()

	// 创建组件实例
	MyComponent.create(myEntity, {
		value1: true,
		value2: 10,
	})

	// 订阅变更
	MyComponent.onChange(myEntity, (componentData) => {
		if (!componentData) return
		console.log(componentData.value1)
		console.log(componentData.value2)
	})
}
```

你也可以将这种方法与 [查询组件](/creator/content-creator-zh/chang-jing-sdk7/jia-gou/querying-components.md)结合起来，以便批量订阅场景中每个拥有特定组件的实体，并将其绑定到各自的函数。

```ts
export function main() {
	for (const [entity] of engine.getEntitiesWith(MyComponent)) {
		MyComponent.onChange(entity, (componentData) => {
			if (!componentData) return
			console.log(componentData.value1)
			console.log(componentData.value2)
		})
	}
}
```

请注意，这种方法只会订阅 `onChange()` 场景开始时就已存在的实体，例如通过该 UI 创建的实体 [创作者中心](/creator/content-creator-zh/chang-jing-bian-ji-qi/kai-shi-shi-yong/about-editor.md).

{% hint style="info" %}
**💡 提示**: 如果你更愿意处理不一定与组件变化相关的事件，我们建议导入 TypeScript 库 [Mitt](https://www.npmjs.com/package/mitt) 到你的场景中。该库提供了用于触发和监听事件的简单函数。
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/jia-gou/subscribe-to-changes.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
