1# NodeContainer 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @xiang-shouxing--> 5<!--Designer: @xiang-shouxing--> 6<!--Tester: @sally__--> 7<!--Adviser: @HelloCrease--> 8 9基础组件,用于挂载自定义节点(如[FrameNode](../js-apis-arkui-frameNode.md)或[BuilderNode](../js-apis-arkui-builderNode.md)),并通过[NodeController](../js-apis-arkui-nodeController.md)动态控制节点的上树和下树。组件不支持尾随添加子节点,接受一个[NodeController](../js-apis-arkui-nodeController.md)实例接口,需与NodeController组合使用。 10 11> **说明:** 12> 13> 该组件从API version 11开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 14> 15> 该组件下仅支持挂载自定义节点[FrameNode](../js-apis-arkui-frameNode.md)或者是[BuilderNode](../js-apis-arkui-builderNode.md)中获取的根节点FrameNode。 16> 不支持挂载查询获得的系统组件[代理节点](../js-apis-arkui-frameNode.md#ismodifiable12)。 17> 18> 当前不支持使用[动态属性设置](./ts-universal-attributes-attribute-modifier.md)。 19> 20> 该组件下的节点树构建中会使用UI实例[UIContext](../arkts-apis-uicontext-uicontext.md),当实例切换时可能会因为实例不匹配而出现问题,因此该组件当前不支持跨实例的节点复用。 21> 22> 该组件未销毁时,不会主动触发挂载节点的下树。 23 24## 子组件 25 26不支持子组件。 27 28## 接口 29 30### NodeContainer 31 32NodeContainer(controller: NodeController) 33 34**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 35 36**系统能力:** SystemCapability.ArkUI.ArkUI.Full 37 38**参数:** 39 40| 参数名 | 类型 | 必填 | 说明 | 41| ---------- | ---------------------------------------------------- | ---- | ------------------------------------------------------------ | 42| controller | [NodeController](../js-apis-arkui-nodeController.md) | 是 | NodeController用于控制NodeContainer中的节点的上树和下树,反映NodeContainer容器的生命周期。 | 43## 属性 44 45支持[通用属性](ts-component-general-attributes.md)。 46 47## 事件 48 49支持[通用事件](ts-component-general-events.md)。 50 51## 示例 52 53通过NodeController挂载BuilderNode节点。 54 55```ts 56import { NodeController, BuilderNode, FrameNode, UIContext } from '@kit.ArkUI'; 57 58declare class Params { 59 text: string 60} 61 62@Builder 63function buttonBuilder(params: Params) { 64 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceEvenly }) { 65 Text(params.text) 66 .fontSize(12) 67 Button(`This is a Button`, { type: ButtonType.Normal, stateEffect: true }) 68 .fontSize(12) 69 .borderRadius(8) 70 .backgroundColor(0x317aff) 71 } 72 .height(100) 73 .width(200) 74} 75 76class MyNodeController extends NodeController { 77 private rootNode: BuilderNode<[Params]> | null = null; 78 private wrapBuilder: WrappedBuilder<[Params]> = wrapBuilder(buttonBuilder); 79 80 makeNode(uiContext: UIContext): FrameNode | null { 81 if (this.rootNode === null) { 82 this.rootNode = new BuilderNode(uiContext); 83 this.rootNode.build(this.wrapBuilder, { text: "This is a Text" }) 84 } 85 return this.rootNode.getFrameNode(); 86 } 87} 88 89 90@Entry 91@Component 92struct Index { 93 private baseNode: MyNodeController = new MyNodeController() 94 95 build() { 96 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceEvenly }) { 97 Text("This is a NodeContainer contains a text and a button ") 98 .fontSize(9) 99 .fontColor(0xCCCCCC) 100 NodeContainer(this.baseNode) 101 .borderWidth(1) 102 .onClick(() => { 103 console.log("click event"); 104 }) 105 } 106 .padding({ left: 35, right: 35, top: 35 }) 107 .height(200) 108 .width(300) 109 } 110} 111``` 112