# ComponentContent ComponentContent表示组件内容的实体封装,其对象支持在非UI组件中创建与传递,便于开发者对弹窗类组件进行解耦封装。ComponentContent底层使用了BuilderNode,相关使用规格参考[BuilderNode](js-apis-arkui-builderNode.md)。 > **说明:** > > 本模块从API version 12开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 > > 当前不支持在预览器中使用ComponentContent。 ## 导入模块 ```ts import { ComponentContent } from '@kit.ArkUI'; ``` ## ComponentContent ### constructor constructor(uiContext: UIContext, builder: WrappedBuilder\<[]>) ComponentContent的构造函数。 **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 **系统能力:** SystemCapability.ArkUI.ArkUI.Full **参数:** | 参数名 | 类型 | 必填 | 说明 | | --------- | ----------------------------------------- | ---- | ---------------------------------- | | uiContext | [UIContext](./js-apis-arkui-UIContext.md) | 是 | 创建对应节点时候所需要的UI上下文。 | | builder | [WrappedBuilder\<[]>](../../ui/state-management/arkts-wrapBuilder.md) | 是 | 封装不带参builder函数的WrappedBuilder对象。 | ### constructor constructor(uiContext: UIContext, builder: WrappedBuilder\<[T]>, args: T) ComponentContent的构造函数。 **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 **系统能力:** SystemCapability.ArkUI.ArkUI.Full **参数:** | 参数名 | 类型 | 必填 | 说明 | | --------- | ----------------------------------------- | ---- | ---------------------------------- | | uiContext | [UIContext](./js-apis-arkui-UIContext.md) | 是 | 创建对应节点时候所需要的UI上下文。 | | builder | [WrappedBuilder\<[T]>](../../ui/state-management/arkts-wrapBuilder.md) | 是 | 封装带参builder函数的WrappedBuilder对象。 | | args | T | 是 | WrappedBuilder对象封装的builder函数的参数。 | ### constructor constructor(uiContext: UIContext, builder: WrappedBuilder\<[T]>, args: T, options: BuildOptions) ComponentContent的构造函数。 **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 **系统能力:** SystemCapability.ArkUI.ArkUI.Full **参数:** | 参数名 | 类型 | 必填 | 说明 | | --------- | ----------------------------------------- | ---- | ---------------------------------- | | uiContext | [UIContext](./js-apis-arkui-UIContext.md) | 是 | 创建对应节点时候所需要的UI上下文。 | | builder | [WrappedBuilder\<[T]>](../../ui/state-management/arkts-wrapBuilder.md) | 是 | 封装带参builder函数的WrappedBuilder对象。 | | args | T | 是 | WrappedBuilder对象封装的builder函数的参数。 | | options | [BuildOptions](./js-apis-arkui-builderNode.md#buildoptions12) | 是 | build的配置参数,判断是否支持@Builder中嵌套@Builder的行为。 | **示例:** ``` ts import { ComponentContent, NodeContent, typeNode } from "@kit.ArkUI" interface ParamsInterface { text: string; func: Function; } @Builder function buildTextWithFunc(fun: Function) { Text(fun()) .fontSize(50) .fontWeight(FontWeight.Bold) .margin({ bottom: 36 }) } @Builder function buildText(params: ParamsInterface) { Column() { Text(params.text) .fontSize(50) .fontWeight(FontWeight.Bold) .margin({ bottom: 36 }) buildTextWithFunc(params.func) } } @Entry @Component struct Index { @State message: string = "HELLO" private content: NodeContent = new NodeContent(); build() { Row() { Column() { Button('addComponentContent') .onClick(() => { let column = typeNode.createNode(this.getUIContext(), "Column"); column.initialize(); column.addComponentContent(new ComponentContent(this.getUIContext(), wrapBuilder<[ParamsInterface]>(buildText), { text: this.message, func: () => { return "FUNCTION" } }, { nestingBuilderSupported: true })) this.content.addFrameNode(column); }) ContentSlot(this.content) } .id("column") .width('100%') .height('100%') } .height('100%') } } ``` ### update update(args: T): void 用于更新WrappedBuilder对象封装的builder函数参数,与constructor传入的参数类型保持一致。 **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 **系统能力:** SystemCapability.ArkUI.ArkUI.Full **参数:** | 参数名 | 类型 | 必填 | 说明 | | ------ | ---- | ---- | ------------------------------------------------------------ | | args | T | 是 | 用于更新WrappedBuilder对象封装的builder函数参数,与constructor传入的参数类型保持一致。 | **示例:** ```ts import { ComponentContent } from "@kit.ArkUI"; class Params { text: string = "" constructor(text: string) { this.text = text; } } @Builder function buildText(params: Params) { Column() { Text(params.text) .fontSize(50) .fontWeight(FontWeight.Bold) .margin({bottom: 36}) }.backgroundColor('#FFF0F0F0') } @Entry @Component struct Index { @State message: string = "hello" build() { Row() { Column() { Button("click me") .onClick(() => { let uiContext = this.getUIContext(); let promptAction = uiContext.getPromptAction(); let contentNode = new ComponentContent(uiContext, wrapBuilder(buildText), new Params(this.message)); promptAction.openCustomDialog(contentNode); setTimeout(() => { contentNode.update(new Params("new message")); }, 2000); //2秒后自动更新弹窗内容文本 }) } .width('100%') .height('100%') } .height('100%') } } ``` ### reuse reuse(param?: Object): void 传递reuse事件到ComponentContent中的自定义组件。 **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 **系统能力:** SystemCapability.ArkUI.ArkUI.Full **参数:** | 参数名 | 类型 | 必填 | 说明 | | ------ | ------ | ---- | ------------------------------------------------------------------------ | | param | Object | 否 | 用于复用WrappedBuilder对象封装的builder函数参数,与constructor传入的参数类型保持一致。 | ### recycle recycle(): void 传递recycle事件到ComponentContent中的自定义组件。 **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 **系统能力:** SystemCapability.ArkUI.ArkUI.Full ```ts import { NodeContent, typeNode, ComponentContent } from "@kit.ArkUI"; const TEST_TAG: string = "Reuse+Recycle"; class MyDataSource { private dataArray: string[] = []; private listener: DataChangeListener | null = null public totalCount(): number { return this.dataArray.length; } public getData(index: number) { return this.dataArray[index]; } public pushData(data: string) { this.dataArray.push(data); } public reloadListener(): void { this.listener?.onDataReloaded(); } public registerDataChangeListener(listener: DataChangeListener): void { this.listener = listener; } public unregisterDataChangeListener(): void { this.listener = null; } } class Params { item: string = ''; constructor(item: string) { this.item = item; } } @Builder function buildNode(param: Params = new Params("hello")) { Row() { Text(`C${param.item} -- `) ReusableChildComponent2({ item: param.item }) //该自定义组件在ComponentContent中无法被正确复用 } } // 被回收复用的自定义组件,其状态变量会更新,而子自定义组件ReusableChildComponent3中的状态变量也会更新,但ComponentContent会阻断这一传递过程 @Reusable @Component struct ReusableChildComponent { @Prop item: string = ''; @Prop switch: string = ''; private content: NodeContent = new NodeContent(); private componentContent: ComponentContent = new ComponentContent( this.getUIContext(), wrapBuilder<[Params]>(buildNode), new Params(this.item), { nestingBuilderSupported: true }); aboutToAppear() { let column = typeNode.createNode(this.getUIContext(), "Column"); column.initialize(); column.addComponentContent(this.componentContent); this.content.addFrameNode(column); } aboutToRecycle(): void { console.log(`${TEST_TAG} ReusableChildComponent aboutToRecycle ${this.item}`); // 当开关为open,通过ComponentContent的reuse接口和recycle接口传递给其下的自定义组件,例如ReusableChildComponent2,完成复用 if (this.switch === 'open') { this.componentContent.recycle(); } } aboutToReuse(params: object): void { console.log(`${TEST_TAG} ReusableChildComponent aboutToReuse ${JSON.stringify(params)}`); // 当开关为open,通过ComponentContent的reuse接口和recycle接口传递给其下的自定义组件,例如ReusableChildComponent2,完成复用 if (this.switch === 'open') { this.componentContent.reuse(params); } } build() { Row() { Text(`A${this.item}--`) ReusableChildComponent3({ item: this.item }) ContentSlot(this.content) } } } @Component struct ReusableChildComponent2 { @Prop item: string = "false"; aboutToReuse(params: Record) { console.log(`${TEST_TAG} ReusableChildComponent2 aboutToReuse ${JSON.stringify(params)}`); } aboutToRecycle(): void { console.log(`${TEST_TAG} ReusableChildComponent2 aboutToRecycle ${this.item}`); } build() { Row() { Text(`D${this.item}`) .fontSize(20) .backgroundColor(Color.Yellow) .margin({ left: 10 }) }.margin({ left: 10, right: 10 }) } } @Component struct ReusableChildComponent3 { @Prop item: string = "false"; aboutToReuse(params: Record) { console.log(`${TEST_TAG} ReusableChildComponent3 aboutToReuse ${JSON.stringify(params)}`); } aboutToRecycle(): void { console.log(`${TEST_TAG} ReusableChildComponent3 aboutToRecycle ${this.item}`); } build() { Row() { Text(`B${this.item}`) .fontSize(20) .backgroundColor(Color.Yellow) .margin({ left: 10 }) }.margin({ left: 10, right: 10 }) } } @Entry @Component struct Index { @State data: MyDataSource = new MyDataSource(); aboutToAppear() { for (let i = 0; i < 100; i++) { this.data.pushData(i.toString()); } } build() { Column() { List({ space: 3 }) { LazyForEach(this.data, (item: string) => { ListItem() { ReusableChildComponent({ item: item, switch: 'open' // 将open改为close可观察到,ComponentContent不通过reuse和recycle接口传递复用时,ComponentContent内部的自定义组件的行为表现 }) } }, (item: string) => item) } .width('100%') .height('100%') } } } ``` ### dispose dispose(): void 立即释放当前ComponentContent,即ComponentContent对象与后端实体节点解除引用关系。 **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 **系统能力:** SystemCapability.ArkUI.ArkUI.Full **示例:** ```ts import { BusinessError } from '@kit.BasicServicesKit'; import { ComponentContent } from '@kit.ArkUI'; class Params { text: string = "" constructor(text: string) { this.text = text; } } @Builder function buildText(params: Params) { Column() { Text(params.text) .fontSize(50) .fontWeight(FontWeight.Bold) .margin({bottom: 36}) }.backgroundColor('#FFF0F0F0') } @Entry @Component struct Index { @State message: string = "hello" build() { Row() { Column() { Button("click me") .onClick(() => { let uiContext = this.getUIContext(); let promptAction = uiContext.getPromptAction(); let contentNode = new ComponentContent(uiContext, wrapBuilder(buildText), new Params(this.message)); promptAction.openCustomDialog(contentNode); setTimeout(() => { promptAction.closeCustomDialog(contentNode) .then(() => { console.info('customdialog closed.') if (contentNode !== null) { contentNode.dispose(); //释放contentNode } }).catch((error: BusinessError) => { let message = (error as BusinessError).message; let code = (error as BusinessError).code; console.error(`closeCustomDialog args error code is ${code}, message is ${message}`); }) }, 2000); //2秒后自动关闭 }) } .width('100%') .height('100%') } .height('100%') } } ``` ### updateConfiguration updateConfiguration(): void 传递[系统环境变化](../apis-ability-kit/js-apis-app-ability-configuration.md)事件,触发节点的全量更新。 **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 **系统能力:** SystemCapability.ArkUI.ArkUI.Full > **说明:** > > updateConfiguration接口功能为通知对象更新,更新所使用的系统环境由当前的系统环境变化。 **示例:** ```ts import { NodeController, FrameNode, ComponentContent } from '@kit.ArkUI'; import { AbilityConstant, Configuration, EnvironmentCallback, ConfigurationConstant } from '@kit.AbilityKit'; @Builder function buildText() { Column() { Text('Hello') .fontSize(36) .fontWeight(FontWeight.Bold) } .backgroundColor($r('sys.color.ohos_id_color_background')) .width('100%') .alignItems(HorizontalAlign.Center) .padding(16) } const componentContentMap: Array> = new Array(); class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { return this.rootNode; } createNode(context: UIContext) { this.rootNode = new FrameNode(context); let component = new ComponentContent(context, wrapBuilder(buildText)); componentContentMap.push(component); this.rootNode.addComponentContent(component); } deleteNode() { let node = componentContentMap.pop(); this.rootNode?.dispose(); node?.dispose(); } } function updateColorMode() { componentContentMap.forEach((value, index) => { value.updateConfiguration(); }) } @Entry @Component struct FrameNodeTypeTest { private myNodeController: MyNodeController = new MyNodeController(); aboutToAppear(): void { let environmentCallback: EnvironmentCallback = { onMemoryLevel: (level: AbilityConstant.MemoryLevel): void => { console.log('onMemoryLevel'); }, onConfigurationUpdated: (config: Configuration): void => { console.log('onConfigurationUpdated ' + JSON.stringify(config)); updateColorMode(); } } // 注册监听回调 this.getUIContext().getHostContext()?.getApplicationContext().on('environment', environmentCallback); // 设置应用深浅色跟随系统 this.getUIContext() .getHostContext()?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); this.myNodeController.createNode(this.getUIContext()); } aboutToDisappear(): void { //移除map中的引用,并将自定义节点释放 this.myNodeController.deleteNode(); } build() { Column({ space: 16 }) { NodeContainer(this.myNodeController); Button('切换深色') .onClick(() => { this.getUIContext() .getHostContext()?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_DARK); }) Button('设置浅色') .onClick(() => { this.getUIContext() .getHostContext()?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT); }) } } } ```