• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# ComponentContent
2
3ComponentContent表示组件内容的实体封装,其对象支持在非UI组件中创建与传递,便于开发者对弹窗类组件进行解耦封装。ComponentContent底层使用了BuilderNode,相关使用规格参考[BuilderNode](js-apis-arkui-builderNode.md)。
4
5> **说明:**
6>
7> 本模块从API version 12开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。
8>
9> 当前不支持在预览器中使用ComponentContent。
10
11
12## 导入模块
13
14```ts
15import { ComponentContent } from '@kit.ArkUI';
16```
17
18## ComponentContent
19
20### constructor
21
22constructor(uiContext: UIContext, builder: WrappedBuilder\<[]>)
23
24ComponentContent的构造函数。
25
26**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
27
28**系统能力:** SystemCapability.ArkUI.ArkUI.Full
29
30**参数:**
31
32| 参数名    | 类型                                      | 必填 | 说明                               |
33| --------- | ----------------------------------------- | ---- | ---------------------------------- |
34| uiContext | [UIContext](./js-apis-arkui-UIContext.md) | 是   | 创建对应节点时候所需要的UI上下文。 |
35| builder  | [WrappedBuilder\<[]>](../../ui/state-management/arkts-wrapBuilder.md) | 是   |   封装不带参builder函数的WrappedBuilder对象。 |
36
37### constructor
38
39constructor(uiContext: UIContext, builder: WrappedBuilder\<[T]>, args: T)
40
41ComponentContent的构造函数。
42
43**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
44
45**系统能力:** SystemCapability.ArkUI.ArkUI.Full
46
47**参数:**
48
49| 参数名    | 类型                                      | 必填 | 说明                               |
50| --------- | ----------------------------------------- | ---- | ---------------------------------- |
51| uiContext | [UIContext](./js-apis-arkui-UIContext.md) | 是   | 创建对应节点时候所需要的UI上下文。 |
52| builder  | [WrappedBuilder\<[T]>](../../ui/state-management/arkts-wrapBuilder.md) | 是   |   封装带参builder函数的WrappedBuilder对象。 |
53| args     |     T     |   是   |   WrappedBuilder对象封装的builder函数的参数。 |
54
55### constructor
56
57  constructor(uiContext: UIContext, builder: WrappedBuilder\<[T]>, args: T, options: BuildOptions)
58
59ComponentContent的构造函数。
60
61**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
62
63**系统能力:** SystemCapability.ArkUI.ArkUI.Full
64
65**参数:**
66
67| 参数名    | 类型                                      | 必填 | 说明                               |
68| --------- | ----------------------------------------- | ---- | ---------------------------------- |
69| uiContext | [UIContext](./js-apis-arkui-UIContext.md) | 是   | 创建对应节点时候所需要的UI上下文。 |
70| builder  | [WrappedBuilder\<[T]>](../../ui/state-management/arkts-wrapBuilder.md) | 是   |   封装带参builder函数的WrappedBuilder对象。 |
71| args     |     T     |   是   |   WrappedBuilder对象封装的builder函数的参数。 |
72| options | [BuildOptions](./js-apis-arkui-builderNode.md#buildoptions12)                                                    | 是   |  build的配置参数,判断是否支持@Builder中嵌套@Builder的行为。                                         |
73
74**示例:**
75``` ts
76import { ComponentContent, NodeContent, typeNode } from "@kit.ArkUI"
77
78interface ParamsInterface {
79  text: string;
80  func: Function;
81}
82
83@Builder
84function buildTextWithFunc(fun: Function) {
85  Text(fun())
86    .fontSize(50)
87    .fontWeight(FontWeight.Bold)
88    .margin({ bottom: 36 })
89}
90
91@Builder
92function buildText(params: ParamsInterface) {
93  Column() {
94    Text(params.text)
95      .fontSize(50)
96      .fontWeight(FontWeight.Bold)
97      .margin({ bottom: 36 })
98    buildTextWithFunc(params.func)
99  }
100}
101
102@Entry
103@Component
104struct Index {
105  @State message: string = "HELLO"
106  private content: NodeContent = new NodeContent();
107
108  build() {
109    Row() {
110      Column() {
111        Button('addComponentContent')
112          .onClick(() => {
113            let column = typeNode.createNode(this.getUIContext(), "Column");
114            column.initialize();
115            column.addComponentContent(new ComponentContent<ParamsInterface>(this.getUIContext(),
116              wrapBuilder<[ParamsInterface]>(buildText), {
117                text: this.message, func: () => {
118                  return "FUNCTION"
119                }
120              }, { nestingBuilderSupported: true }))
121            this.content.addFrameNode(column);
122          })
123        ContentSlot(this.content)
124      }
125      .id("column")
126      .width('100%')
127      .height('100%')
128    }
129    .height('100%')
130  }
131}
132
133```
134
135### update
136
137update(args: T): void
138
139用于更新WrappedBuilder对象封装的builder函数参数,与constructor传入的参数类型保持一致。
140
141**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
142
143**系统能力:** SystemCapability.ArkUI.ArkUI.Full
144
145**参数:**
146
147| 参数名 | 类型 | 必填 | 说明                                                         |
148| ------ | ---- | ---- | ------------------------------------------------------------ |
149| args   | T    | 是   | 用于更新WrappedBuilder对象封装的builder函数参数,与constructor传入的参数类型保持一致。 |
150
151**示例:**
152
153```ts
154import { ComponentContent } from "@kit.ArkUI";
155
156class Params {
157  text: string = ""
158  constructor(text: string) {
159    this.text = text;
160  }
161}
162
163@Builder
164function buildText(params: Params) {
165  Column() {
166    Text(params.text)
167      .fontSize(50)
168      .fontWeight(FontWeight.Bold)
169      .margin({bottom: 36})
170  }.backgroundColor('#FFF0F0F0')
171}
172
173@Entry
174@Component
175struct Index {
176  @State message: string = "hello"
177
178  build() {
179    Row() {
180      Column() {
181        Button("click me")
182            .onClick(() => {
183                let uiContext = this.getUIContext();
184                let promptAction = uiContext.getPromptAction();
185                let contentNode = new ComponentContent(uiContext, wrapBuilder(buildText), new Params(this.message));
186                promptAction.openCustomDialog(contentNode);
187
188                setTimeout(() => {
189                  contentNode.update(new Params("new message"));
190                }, 2000);    //2秒后自动更新弹窗内容文本
191            })
192      }
193      .width('100%')
194      .height('100%')
195    }
196    .height('100%')
197  }
198}
199```
200
201### reuse
202
203reuse(param?: Object): void
204
205传递reuse事件到ComponentContent中的自定义组件。
206
207**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
208
209**系统能力:** SystemCapability.ArkUI.ArkUI.Full
210
211**参数:**
212
213| 参数名 | 类型   | 必填 | 说明                                                                     |
214| ------ | ------ | ---- | ------------------------------------------------------------------------ |
215| param  | Object | 否   | 用于复用WrappedBuilder对象封装的builder函数参数,与constructor传入的参数类型保持一致。 |
216
217### recycle
218
219recycle(): void
220
221传递recycle事件到ComponentContent中的自定义组件。
222
223**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
224
225**系统能力:** SystemCapability.ArkUI.ArkUI.Full
226
227```ts
228import { NodeContent, typeNode, ComponentContent } from "@kit.ArkUI";
229
230const TEST_TAG: string = "Reuse+Recycle";
231
232class MyDataSource {
233  private dataArray: string[] = [];
234  private listener: DataChangeListener | null = null
235
236  public totalCount(): number {
237    return this.dataArray.length;
238  }
239
240  public getData(index: number) {
241    return this.dataArray[index];
242  }
243
244  public pushData(data: string) {
245    this.dataArray.push(data);
246  }
247
248  public reloadListener(): void {
249    this.listener?.onDataReloaded();
250  }
251
252  public registerDataChangeListener(listener: DataChangeListener): void {
253    this.listener = listener;
254  }
255
256  public unregisterDataChangeListener(): void {
257    this.listener = null;
258  }
259}
260
261class Params {
262  item: string = '';
263
264  constructor(item: string) {
265    this.item = item;
266  }
267}
268
269@Builder
270function buildNode(param: Params = new Params("hello")) {
271  Row() {
272    Text(`C${param.item} -- `)
273    ReusableChildComponent2({ item: param.item }) //该自定义组件在ComponentContent中无法被正确复用
274  }
275}
276
277// 被回收复用的自定义组件,其状态变量会更新,而子自定义组件ReusableChildComponent3中的状态变量也会更新,但ComponentContent会阻断这一传递过程
278@Reusable
279@Component
280struct ReusableChildComponent {
281  @Prop item: string = '';
282  @Prop switch: string = '';
283  private content: NodeContent = new NodeContent();
284  private componentContent: ComponentContent<Params> = new ComponentContent<Params>(
285    this.getUIContext(),
286    wrapBuilder<[Params]>(buildNode),
287    new Params(this.item),
288    { nestingBuilderSupported: true });
289
290  aboutToAppear() {
291    let column = typeNode.createNode(this.getUIContext(), "Column");
292    column.initialize();
293    column.addComponentContent(this.componentContent);
294    this.content.addFrameNode(column);
295  }
296
297  aboutToRecycle(): void {
298    console.log(`${TEST_TAG} ReusableChildComponent aboutToRecycle ${this.item}`);
299
300    // 当开关为open,通过ComponentContent的reuse接口和recycle接口传递给其下的自定义组件,例如ReusableChildComponent2,完成复用
301    if (this.switch === 'open') {
302      this.componentContent.recycle();
303    }
304  }
305
306  aboutToReuse(params: object): void {
307    console.log(`${TEST_TAG} ReusableChildComponent aboutToReuse ${JSON.stringify(params)}`);
308
309    // 当开关为open,通过ComponentContent的reuse接口和recycle接口传递给其下的自定义组件,例如ReusableChildComponent2,完成复用
310    if (this.switch === 'open') {
311      this.componentContent.reuse(params);
312    }
313  }
314
315  build() {
316    Row() {
317      Text(`A${this.item}--`)
318      ReusableChildComponent3({ item: this.item })
319      ContentSlot(this.content)
320    }
321  }
322}
323
324@Component
325struct ReusableChildComponent2 {
326  @Prop item: string = "false";
327
328  aboutToReuse(params: Record<string, object>) {
329    console.log(`${TEST_TAG} ReusableChildComponent2 aboutToReuse ${JSON.stringify(params)}`);
330  }
331
332  aboutToRecycle(): void {
333    console.log(`${TEST_TAG} ReusableChildComponent2 aboutToRecycle ${this.item}`);
334  }
335
336  build() {
337    Row() {
338      Text(`D${this.item}`)
339        .fontSize(20)
340        .backgroundColor(Color.Yellow)
341        .margin({ left: 10 })
342    }.margin({ left: 10, right: 10 })
343  }
344}
345
346@Component
347struct ReusableChildComponent3 {
348  @Prop item: string = "false";
349
350  aboutToReuse(params: Record<string, object>) {
351    console.log(`${TEST_TAG} ReusableChildComponent3 aboutToReuse ${JSON.stringify(params)}`);
352  }
353
354  aboutToRecycle(): void {
355    console.log(`${TEST_TAG} ReusableChildComponent3 aboutToRecycle ${this.item}`);
356  }
357
358  build() {
359    Row() {
360      Text(`B${this.item}`)
361        .fontSize(20)
362        .backgroundColor(Color.Yellow)
363        .margin({ left: 10 })
364    }.margin({ left: 10, right: 10 })
365  }
366}
367
368
369@Entry
370@Component
371struct Index {
372  @State data: MyDataSource = new MyDataSource();
373
374  aboutToAppear() {
375    for (let i = 0; i < 100; i++) {
376      this.data.pushData(i.toString());
377    }
378  }
379
380  build() {
381    Column() {
382      List({ space: 3 }) {
383        LazyForEach(this.data, (item: string) => {
384          ListItem() {
385            ReusableChildComponent({
386              item: item,
387              switch: 'open' // 将open改为close可观察到,ComponentContent不通过reuse和recycle接口传递复用时,ComponentContent内部的自定义组件的行为表现
388            })
389          }
390        }, (item: string) => item)
391      }
392      .width('100%')
393      .height('100%')
394    }
395  }
396}
397```
398
399### dispose
400
401dispose(): void
402
403立即释放当前ComponentContent,即ComponentContent对象与后端实体节点解除引用关系。
404
405**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
406
407**系统能力:** SystemCapability.ArkUI.ArkUI.Full
408
409**示例:**
410
411```ts
412import { BusinessError } from '@kit.BasicServicesKit';
413import { ComponentContent } from '@kit.ArkUI';
414
415class Params {
416  text: string = ""
417  constructor(text: string) {
418    this.text = text;
419  }
420}
421
422@Builder
423function buildText(params: Params) {
424  Column() {
425    Text(params.text)
426      .fontSize(50)
427      .fontWeight(FontWeight.Bold)
428      .margin({bottom: 36})
429  }.backgroundColor('#FFF0F0F0')
430}
431
432@Entry
433@Component
434struct Index {
435  @State message: string = "hello"
436
437  build() {
438    Row() {
439      Column() {
440        Button("click me")
441            .onClick(() => {
442                let uiContext = this.getUIContext();
443                let promptAction = uiContext.getPromptAction();
444                let contentNode = new ComponentContent(uiContext, wrapBuilder(buildText), new Params(this.message));
445                promptAction.openCustomDialog(contentNode);
446
447                setTimeout(() => {
448                  promptAction.closeCustomDialog(contentNode)
449                    .then(() => {
450                      console.info('customdialog closed.')
451                      if (contentNode !== null) {
452                        contentNode.dispose();   //释放contentNode
453                      }
454                    }).catch((error: BusinessError) => {
455                      let message = (error as BusinessError).message;
456                      let code = (error as BusinessError).code;
457                      console.error(`closeCustomDialog args error code is ${code}, message is ${message}`);
458                    })
459                }, 2000);     //2秒后自动关闭
460            })
461      }
462      .width('100%')
463      .height('100%')
464    }
465    .height('100%')
466  }
467}
468```
469
470
471### updateConfiguration
472
473updateConfiguration(): void
474
475传递[系统环境变化](../apis-ability-kit/js-apis-app-ability-configuration.md)事件,触发节点的全量更新。
476
477**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
478
479**系统能力:** SystemCapability.ArkUI.ArkUI.Full
480
481> **说明:**
482>
483> updateConfiguration接口功能为通知对象更新,更新所使用的系统环境由当前的系统环境变化。
484
485**示例:**
486```ts
487import { NodeController, FrameNode, ComponentContent } from '@kit.ArkUI';
488import { AbilityConstant, Configuration, EnvironmentCallback, ConfigurationConstant } from '@kit.AbilityKit';
489
490@Builder
491function buildText() {
492  Column() {
493    Text('Hello')
494      .fontSize(36)
495      .fontWeight(FontWeight.Bold)
496  }
497  .backgroundColor($r('sys.color.ohos_id_color_background'))
498  .width('100%')
499  .alignItems(HorizontalAlign.Center)
500  .padding(16)
501}
502
503const componentContentMap: Array<ComponentContent<[Object]>> = new Array();
504
505class MyNodeController extends NodeController {
506  private rootNode: FrameNode | null = null;
507
508  makeNode(uiContext: UIContext): FrameNode | null {
509    return this.rootNode;
510  }
511
512  createNode(context: UIContext) {
513    this.rootNode = new FrameNode(context);
514    let component = new ComponentContent<Object>(context, wrapBuilder(buildText));
515    componentContentMap.push(component);
516    this.rootNode.addComponentContent(component);
517  }
518
519  deleteNode() {
520    let node = componentContentMap.pop();
521    this.rootNode?.dispose();
522    node?.dispose();
523  }
524}
525
526function updateColorMode() {
527  componentContentMap.forEach((value, index) => {
528    value.updateConfiguration();
529  })
530}
531
532@Entry
533@Component
534struct FrameNodeTypeTest {
535  private myNodeController: MyNodeController = new MyNodeController();
536
537  aboutToAppear(): void {
538    let environmentCallback: EnvironmentCallback = {
539      onMemoryLevel: (level: AbilityConstant.MemoryLevel): void => {
540        console.log('onMemoryLevel');
541      },
542      onConfigurationUpdated: (config: Configuration): void => {
543        console.log('onConfigurationUpdated ' + JSON.stringify(config));
544        updateColorMode();
545      }
546    }
547    // 注册监听回调
548    this.getUIContext().getHostContext()?.getApplicationContext().on('environment', environmentCallback);
549    // 设置应用深浅色跟随系统
550    this.getUIContext()
551      .getHostContext()?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
552    this.myNodeController.createNode(this.getUIContext());
553  }
554
555  aboutToDisappear(): void {
556    //移除map中的引用,并将自定义节点释放
557    this.myNodeController.deleteNode();
558  }
559
560  build() {
561    Column({ space: 16 }) {
562      NodeContainer(this.myNodeController);
563      Button('切换深色')
564        .onClick(() => {
565          this.getUIContext()
566            .getHostContext()?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_DARK);
567        })
568      Button('设置浅色')
569        .onClick(() => {
570          this.getUIContext()
571            .getHostContext()?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT);
572        })
573    }
574  }
575}
576```
577