1# NodeController 2 3NodeController用于实现自定义节点的创建、显示、更新等操作的管理,并负责将自定义节点挂载到[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)上。 4 5> **说明:** 6> 7> 本模块首批接口从API version 11开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 8> 9> 当前不支持在预览器中使用NodeController。 10 11## 导入模块 12 13```ts 14import { NodeController } from '@kit.ArkUI'; 15``` 16 17## NodeController 18 19通常搭配[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)进行使用。用于创建控制器管理绑定的[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)组件。一个NodeController只允许与一个[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)进行绑定。 20 21**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 22 23**系统能力:** SystemCapability.ArkUI.ArkUI.Full 24 25### makeNode 26 27abstract makeNode(uiContext : UIContext): FrameNode | null 28 29当实例绑定的[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)创建的时候进行回调。回调方法将返回一个节点,将该节点挂载至[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)。 30或者可以通过NodeController的rebuild()方法进行回调的触发。 31 32**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 33 34**系统能力:** SystemCapability.ArkUI.ArkUI.Full 35 36**参数:** 37 38| 参数名 | 类型 | 必填 | 说明 | 39| --------- | ----------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------- | 40| uiContext | [UIContext](./js-apis-arkui-UIContext.md) | 是 | 回调该方法的时候,绑定[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)的UI上下文。 | 41 42**返回值:** 43 44| 类型 | 说明 | 45| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 46| [FrameNode](./js-apis-arkui-frameNode.md#framenode)\| null | 一个FrameNode对象,返回的节点将被挂载至[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)的占位节点上。若返回null对象,将清空对应[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)的子节点。 | 47 48### aboutToAppear 49 50aboutToAppear?(): void 51 52当NodeController绑定的[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)挂载显示后触发此回调。 53 54> **说明:** 55> 56> 回调时机参考[onAppear](arkui-ts/ts-universal-events-show-hide.md#onappear)。 57 58**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 59 60**系统能力:** SystemCapability.ArkUI.ArkUI.Full 61 62### aboutToDisappear 63 64aboutToDisappear?(): void 65 66当NodeController绑定的[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)卸载消失时触发此回调。 67 68> **说明:** 69> 70> 回调时机参考[onDisAppear](arkui-ts/ts-universal-events-show-hide.md#ondisappear)。 71 72**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 73 74**系统能力:** SystemCapability.ArkUI.ArkUI.Full 75 76### onAttach<sup>18+</sup> 77 78onAttach?(): void 79 80当NodeController绑定的[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)挂载至主节点树时触发此回调。 81 82> **说明:** 83> 84> 回调时机参考[onAttach](arkui-ts/ts-universal-events-show-hide.md#onattach)。 85 86**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。 87 88**系统能力:** SystemCapability.ArkUI.ArkUI.Full 89 90### onDetach<sup>18+</sup> 91 92onDetach?(): void 93 94当NodeController绑定的[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)从主节点树卸载时触发此回调。 95 96> **说明:** 97> 98> 回调时机参考[onDetach](arkui-ts/ts-universal-events-show-hide.md#ondetach)。 99 100**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。 101 102**系统能力:** SystemCapability.ArkUI.ArkUI.Full 103 104### onWillBind<sup>18+</sup> 105 106onWillBind?(containerId: number): void 107 108当NodeController与[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)即将绑定前触发此回调。 109 110**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。 111 112**系统能力:** SystemCapability.ArkUI.ArkUI.Full 113 114**参数:** 115 116| 参数名 | 类型 | 必填 | 说明 | 117| ----------- | ------ |----- |---------------------------------------------------------------------------------------------------------------------------------- | 118| containerId | number | 是 | 回调该方法时,NodeController与NodeContainerId对应的[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)即将绑定。| 119 120### onWillUnbind<sup>18+</sup> 121 122onWillUnbind?(containerId: number): void 123 124当NodeController与[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)即将解绑前触发此回调。 125 126**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。 127 128**系统能力:** SystemCapability.ArkUI.ArkUI.Full 129 130**参数:** 131 132| 参数名 | 类型 | 必填 | 说明 | 133| ----------- | ------ |----- |---------------------------------------------------------------------------------------------------------------------------------- | 134| containerId | number | 是 | 回调该方法时,NodeController与NodeContainerId对应的[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)即将解绑。| 135 136### onBind<sup>18+</sup> 137 138onBind?(containerId: number): void 139 140当NodeController与[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)绑定后触发此回调。 141 142**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。 143 144**系统能力:** SystemCapability.ArkUI.ArkUI.Full 145 146**参数:** 147 148| 参数名 | 类型 | 必填 | 说明 | 149| ----------- | ------ |----- |---------------------------------------------------------------------------------------------------------------------------------- | 150| containerId | number | 是 | 回调该方法时,NodeController与NodeContainerId对应的[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)绑定完成。| 151 152### onUnbind<sup>18+</sup> 153 154onUnbind?(containerId: number): void 155 156当NodeController与[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)解绑后触发此回调。 157 158**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。 159 160**系统能力:** SystemCapability.ArkUI.ArkUI.Full 161 162**参数:** 163 164| 参数名 | 类型 | 必填 | 说明 | 165| ----------- | ------ |----- |---------------------------------------------------------------------------------------------------------------------------------- | 166| containerId | number | 是 | 回调该方法时,NodeController与NodeContainerId对应的[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)解绑完成。| 167 168### aboutToResize 169 170aboutToResize?(size: Size): void 171 172当NodeController绑定的[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)布局的时候触发此回调。 173 174**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 175 176**系统能力:** SystemCapability.ArkUI.ArkUI.Full 177 178**参数:** 179 180| 参数名 | 类型 | 必填 | 说明 | 181| ------ | ---------------------------------------- | ---- | ---------------------------------------- | 182| size | [Size](./js-apis-arkui-graphics.md#size) | 是 | 用于返回组件布局大小的宽和高,单位为vp。 | 183 184### onTouchEvent 185 186onTouchEvent?(event: TouchEvent): void 187 188当NodeController绑定的[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)收到Touch事件时触发此回调。 189 190**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 191 192**系统能力:** SystemCapability.ArkUI.ArkUI.Full 193 194**参数:** 195 196| 参数名 | 类型 | 必填 | 说明 | 197| ------ | ------------------------------------------------------------------------- | ---- | ---------- | 198| event | [TouchEvent](arkui-ts/ts-universal-events-touch.md#touchevent对象说明) | 是 | 触摸事件。 | 199 200### rebuild 201 202rebuild(): void 203 204调用此接口通知[NodeContainer](arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer)组件重新回调[makeNode](#makenode)方法,更改子节点。 205 206**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 207 208**系统能力:** SystemCapability.ArkUI.ArkUI.Full 209 210> **说明:** 211> 由于rebuild方法为应用主动调用的方法,且该操作与UI相关。需要开发者自行保证调用该接口时UI上下文有效,即与绑定的NodeContainer保持UI上下文一致。 212> 213> 监听回调等UI上下文不明确时,可以通过[UIContext](./js-apis-arkui-UIContext.md)的[runScopedTask](./js-apis-arkui-UIContext.md#runscopedtask)方法明确调用时的UI上下文。 214 215## 示例 216 217### 示例1(添加节点布局、Touch、挂载和卸载时的生命周期回调) 218 219该示例通过aboutToResize、onTouchEvent,实现了NodeContainer节点布局、收到Touch事件时的生命周期回调功能。 220 221并通过aboutToAppear、aboutToDisappear接口,实现了NodeContainer节点挂载、卸载时的生命周期回调功能。 222 223通过NodeController挂载BuilderNode节点。 224 225```ts 226import { NodeController, BuilderNode, Size, FrameNode ,UIContext } from '@kit.ArkUI'; 227 228class Params { 229 text: string = "this is a text" 230} 231 232@Builder 233function buttonBuilder(params: Params) { 234 Column() { 235 Button(params.text) 236 .fontSize(12) 237 .borderRadius(8) 238 .borderWidth(2) 239 .backgroundColor(Color.Orange) 240 } 241} 242 243class MyNodeController extends NodeController { 244 private buttonNode: BuilderNode<[Params]> | null = null; 245 private wrapBuilder: WrappedBuilder<[Params]> = wrapBuilder(buttonBuilder); 246 247 makeNode(uiContext: UIContext): FrameNode { 248 if (this.buttonNode == null) { 249 this.buttonNode = new BuilderNode(uiContext); 250 this.buttonNode.build(this.wrapBuilder, { text: "This is a Button" }) 251 } 252 return this.buttonNode!.getFrameNode()!; 253 } 254 255 aboutToResize(size: Size) { 256 console.log("aboutToResize width : " + size.width + " height : " + size.height) 257 } 258 259 aboutToAppear() { 260 console.log("aboutToAppear") 261 } 262 263 aboutToDisappear() { 264 console.log("aboutToDisappear"); 265 } 266 267 onTouchEvent(event:TouchEvent) { 268 console.log("onTouchEvent"); 269 } 270} 271 272@Entry 273@Component 274struct Index { 275 private myNodeController: MyNodeController = new MyNodeController(); 276 277 build() { 278 Column() { 279 NodeContainer(this.myNodeController) 280 } 281 .padding({ left: 35, right: 35, top: 35 }) 282 .width("100%") 283 .height("100%") 284 } 285} 286``` 287 288 289### 示例2(添加节点上下树和绑定解绑前后的生命周期回调) 290 291该示例通过onAttach、onDetach接口,实现了NodeContainer节点上下主节点树的生命周期回调功能。 292 293并通过onWillBind、onWillUnbind、onBind、onUnbind接口,实现了NodeContainer节点绑定和解绑前后的生命周期回调功能。 294 295```ts 296import { NodeController, BuilderNode, Size, FrameNode, UIContext } from '@kit.ArkUI'; 297class Params { 298 text: string = "this is a text" 299} 300 301@Builder 302function buttonBuilder(params: Params) { 303 Column() { 304 Button(params.text) 305 .fontSize(20) 306 .borderRadius(8) 307 .borderWidth(2) 308 .backgroundColor(Color.Grey) 309 } 310} 311 312class MyNodeController extends NodeController { 313 private buttonNode: BuilderNode<[Params]> | null = null; 314 private wrapBuilder: WrappedBuilder<[Params]> = wrapBuilder(buttonBuilder); 315 316 makeNode(uiContext: UIContext): FrameNode { 317 if (this.buttonNode == null) { 318 this.buttonNode = new BuilderNode(uiContext); 319 this.buttonNode.build(this.wrapBuilder, { text: "This is a Button" }) 320 } 321 return this.buttonNode!.getFrameNode()!; 322 } 323 324 onAttach(): void { 325 console.log("myButton on attach"); 326 } 327 328 onDetach(): void { 329 console.log("myButton on detach"); 330 } 331 332 onWillBind(containerId: number): void{ 333 console.log("myButton on WillBind" + containerId); 334 } 335 336 onWillUnbind(containerId: number): void{ 337 console.log("myButton on WillUnbind" + containerId); 338 } 339 340 onBind(containerId: number): void { 341 console.log("myButton on bind: " + containerId); 342 } 343 344 onUnbind(containerId: number): void { 345 console.log("myButton on unbind: " + containerId); 346 } 347} 348 349@Entry 350@Component 351struct Index { 352 @State buttonShow: boolean = true 353 @State buttonIndex: number = 0 354 private buttonController: MyNodeController = new MyNodeController(); 355 private buttonNull: null = null; 356 private buttonControllerArray: Array < MyNodeController | null > = [this.buttonController,this.buttonNull] 357 358 build() { 359 Column() { 360 Row(){ 361 Button("Bind/Unbind") 362 .onClick(() => { 363 this.buttonIndex++; 364 }).margin(5) 365 Button("onAttach/onDetach") 366 .onClick(() => { 367 this.buttonShow = !this.buttonShow 368 }).margin(5) 369 } 370 if(this.buttonShow){ 371 NodeContainer(this.buttonControllerArray[this.buttonIndex % this.buttonControllerArray.length]) 372 } 373 } 374 .padding({ left: 35, right: 35}) 375 .width("100%") 376 .height("100%") 377 } 378} 379``` 380 381