From a2c7910b4d79f2411e8825a090c31604b4b65cbf Mon Sep 17 00:00:00 2001 From: zhangboren Date: Fri, 20 Jun 2025 18:02:02 +0800 Subject: [PATCH] Add ArkTS1.2 wrapBuilder. Signed-off-by: zhangboren --- .../quick-start/arkts-wrapBuilder.md | 149 +++++++++++++++++- .../quick-start/arkts-wrapBuilder.md | 149 +++++++++++++++++- 2 files changed, 290 insertions(+), 8 deletions(-) diff --git a/en/application-dev/quick-start/arkts-wrapBuilder.md b/en/application-dev/quick-start/arkts-wrapBuilder.md index f232d90e346..fd6fef2421d 100644 --- a/en/application-dev/quick-start/arkts-wrapBuilder.md +++ b/en/application-dev/quick-start/arkts-wrapBuilder.md @@ -27,15 +27,31 @@ In the preceding code, **builderArr** is an array consisting of @Builder methods To solve this problem, **wrapBuilder** is introduced as the global @Builder encapsulation function. **wrapBuilder** is a template function that accepts a [global \@Builder decorated function](arkts-builder.md#global-custom-builder-function) as its argument and returns a **WrappedBuilder** object, thereby allowing global \@Builder decorated function to be assigned a value and transferred. +## Modules to Import(ArkTS1.2) + +```js +import { WrappedBuilder, wrapBuilder } from '@ohos.arkui.component'; +``` + ## Available APIs **wrapBuilder** is a template function that returns a **WrappedBuilder** object. +**ArkTS1.1:** + ```ts declare function wrapBuilder< Args extends Object[]>(builder: (...args: Args) => void): WrappedBuilder; ``` + +**ArkTS1.2:** + +```ts +declare function wrapBuilder(builder: T): WrappedBuilder; +``` + The **WrappedBuilder** object is also a template class. +**ArkTS1.1:** ```ts declare class WrappedBuilder< Args extends Object[]> { builder: (...args: Args) => void; @@ -43,31 +59,49 @@ declare class WrappedBuilder< Args extends Object[]> { constructor(builder: (...args: Args) => void); } ``` +>**NOTE**
The template parameter **Args extends Object[]** is a parameter list of the builder function to be wrapped. +**ArkTS1.2:** +```ts +declare class WrappedBuilder { + builder: T; ->**NOTE**
The template parameter **Args extends Object[]** is a parameter list of the builder function to be wrapped. + constructor(builder: T); +} +``` +>**NOTE**
The template parameter **T** is the type of the builder function to be wrapped. Example +**ArkTS1.1:** + ```ts let builderVar: WrappedBuilder<[string, number]> = wrapBuilder(MyBuilder) let builderArr: WrappedBuilder<[string, number]>[] = [wrapBuilder(MyBuilder)] // An array is acceptable. ``` +**ArkTS1.2:** +```ts +let builderVar: WrappedBuilder<@Builder (p1: string, p2: number) => void> = wrapBuilder(MyBuilder) +let builderArr: WrappedBuilder<@Builder (p1: string, p2: number) => void>[] = [wrapBuilder(MyBuilder)] // An array is acceptable. +``` ## Constraints -**wrapBuilder** only accepts a [global \@Builder decorated function](arkts-builder.md#global-custom-builder-function) as its argument. - Of the **WrappedBuilder** object it returns, the **builder** attribute method can be used only inside the struct. +### Global @Builder (ArkTS1.1) + +**wrapBuilder** only accepts a [global \@Builder decorated function](arkts-builder.md#global-custom-builder-function) as its argument. ## Assigning a Value to a Variable Using the @Builder Method The **MyBuilder** method decorated by @Builder is used as the parameter of **wrapBuilder**, and **wrapBuilder** is assigned to the **globalBuilder** variable, which solves the problem that the @Builder method cannot be used after being assigned to the variable. +**ArkTS1.1:** + ```ts @Builder function MyBuilder(value: string, size: number) { @@ -77,6 +111,35 @@ function MyBuilder(value: string, size: number) { let globalBuilder: WrappedBuilder<[string, number]> = wrapBuilder(MyBuilder); +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + Row() { + Column() { + globalBuilder.builder(this.message, 50) + } + .width('100%') + } + .height('100%') + } +} +``` +**ArkTS1.2:** + +```ts +import { WrappedBuilder, wrapBuilder } from '@ohos.arkui.component'; + +@Builder +function MyBuilder(value: string, size: number) { + Text(value) + .fontSize(size) +} + +let globalBuilder: WrappedBuilder<@Builder (p1: string, p2: number) => void> = wrapBuilder(MyBuilder); + @Entry @Component struct Index { @@ -98,6 +161,8 @@ struct Index { In this example, the custom component **Index** uses **ForEach** to render different \@Builder functions. You can use the **wrapBuilder** array declared in **builderArr** to present different \@Builder function effects. In this way, the code is neat. +**ArkTS1.1:** + ``` @Builder function MyBuilder(value: string, size: number) { @@ -137,11 +202,53 @@ struct Index { } } ``` +**ArkTS1.2:** +``` +import { WrappedBuilder, wrapBuilder } from '@ohos.arkui.component'; + +@Builder +function MyBuilder(value: string, size: number) { + Text(value) + .fontSize(size) +} + +@Builder +function YourBuilder(value: string, size: number) { + Text(value) + .fontSize(size) + .fontColor(Color.Pink) +} + +const builderArr: WrappedBuilder<@Builder (p1: string, p2: number) => void>[] = [wrapBuilder(MyBuilder), wrapBuilder(YourBuilder)]; + + +@Entry +@Component +struct Index { + @Builder testBuilder() { + ForEach(builderArr, (item: WrappedBuilder<@Builder (p1: string, p2: number) => void>) => { + item.builder('Hello World', 30) + }) + } + + build() { + Row() { + Column() { + this.testBuilder() + } + .width('100%') + } + .height('100%') + } +} +``` ## Passing Parameters by Reference If parameters are passed in by reference, the UI re-rendering is triggered. +**ArkTS1.1:** + ```ts class Tmp { paramA2: string = 'hello'; @@ -170,9 +277,43 @@ struct Parent{ } ``` +**ArkTS1.2:** + +```ts +import { WrappedBuilder, wrapBuilder } from '@ohos.arkui.component'; +import { Observed } from '@ohos.arkui.stateManagement'; + +@Observed +class Tmp { + paramA2: string = 'hello'; +} + +@Builder function overBuilder(param: () => Tmp) { + Column(){ + Text(`wrapBuildervalue:${param().paramA2}`) + } +} + +const wBuilder: WrappedBuilder<@Builder (param: () => Tmp) => void> = wrapBuilder(overBuilder); + +@Entry +@Component +struct Parent{ + @State label: Tmp = new Tmp(); + build(){ + Column(){ + wBuilder.builder(() => { return {paramA2: this.label.paramA2}; }) + Button('Click me').onClick((e: ClickEvent) => { + this.label.paramA2 = 'ArkUI'; + }) + } + } +} +``` + ## FAQs -### wrapBuilder Redefinition Failure +### wrapBuilder Redefinition Failure(ArkTS1.1) In the same custom component, the same **wrapBuilder** can be initialized only once. In the example, after **builderObj** is initialized through **wrapBuilder(MyBuilderFirst)**, **wrapBuilder(MyBuilderSecond)** does not take effect when a value is assigned to **builderObj** again. diff --git a/zh-cn/application-dev/quick-start/arkts-wrapBuilder.md b/zh-cn/application-dev/quick-start/arkts-wrapBuilder.md index 8645a08ee89..6311ac08eae 100644 --- a/zh-cn/application-dev/quick-start/arkts-wrapBuilder.md +++ b/zh-cn/application-dev/quick-start/arkts-wrapBuilder.md @@ -27,15 +27,28 @@ function testBuilder() { 为了解决这一问题,引入wrapBuilder作为全局@Builder封装函数。wrapBuilder的参数返回WrappedBuilder对象,实现[全局\@Builder](arkts-builder.md#全局自定义构建函数)可以进行赋值和传递。 +## 导入模块(ArkTS1.2) + +```js +import { WrappedBuilder, wrapBuilder } from '@ohos.arkui.component'; +``` ## 接口说明 wrapBuilder是一个模板函数,返回一个`WrappedBuilder`对象。 +**ArkTS1.1:** ```ts declare function wrapBuilder< Args extends Object[]>(builder: (...args: Args) => void): WrappedBuilder; ``` + +**ArkTS1.2:** +```ts +declare function wrapBuilder(builder: T): WrappedBuilder; +``` + 同时 `WrappedBuilder`对象也是一个模板类。 +**ArkTS1.1:** ```ts declare class WrappedBuilder< Args extends Object[]> { builder: (...args: Args) => void; @@ -47,27 +60,48 @@ declare class WrappedBuilder< Args extends Object[]> { >说明:模板参数`Args extends Object[]`是需要包装的builder函数的参数列表 +**ArkTS1.2:** +``` +declare class WrappedBuilder { + builder: T; + + constructor(builder: T); +} +``` + + +>说明:模板参数`T`是需要包装的builder函数的参数列表 + 使用方法: +**ArkTS1.1:** ```ts let builderVar: WrappedBuilder<[string, number]> = wrapBuilder(MyBuilder) let builderArr: WrappedBuilder<[string, number]>[] = [wrapBuilder(MyBuilder)] //可以放入数组 ``` +**ArkTS1.2:** +```ts +let builderVar: WrappedBuilder<@Builder (p1: string, p2: number) => void> = wrapBuilder(MyBuilder) +let builderArr: WrappedBuilder<@Builder (p1: string, p2: number)>[] = [wrapBuilder(MyBuilder)] //可以放入数组 +``` ## 限制条件 -wrapBuilder方法只能传入[全局\@Builder](arkts-builder.md#全局自定义构建函数)方法。 - wrapBuilder方法返回的WrappedBuilder对象的builder属性方法只能在struct内部使用。 +### 全局@Builder(AkTS1.1) + +wrapBuilder方法只能传入[全局\@Builder](arkts-builder.md#全局自定义构建函数)方法。 ## @Builder方法赋值给变量 把@Builder装饰器装饰的方法MyBuilder作为wrapBuilder的参数,再将wrapBuilder赋值给变量globalBuilder,用来解决@Builder方法赋值给变量后无法被使用的问题。 +**ArkTS1.1:** + ```ts @Builder function MyBuilder(value: string, size: number) { @@ -94,10 +128,41 @@ struct Index { } ``` +**ArkTS1.2:** +```ts +import { WrappedBuilder, wrapBuilder } from '@ohos.arkui.component'; + +@Builder +function MyBuilder(value: string, size: number) { + Text(value) + .fontSize(size) +} + +let globalBuilder: WrappedBuilder<@Builder (p1: string, p2: number) => void> = wrapBuilder(MyBuilder); + +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + Row() { + Column() { + globalBuilder.builder(this.message, 50) + } + .width('100%') + } + .height('100%') + } +} +``` + ## @Builder方法赋值给变量在UI语法中使用 自定义组件Index使用ForEach来进行不同\@Builder函数的渲染,可以使用builderArr声明的wrapBuilder数组进行不同\@Builder函数效果体现。整体代码会较整洁。 +**ArkTS1.1:** + ``` @Builder function MyBuilder(value: string, size: number) { @@ -138,10 +203,53 @@ struct Index { } ``` +**ArkTS1.2:** + +``` +import { WrappedBuilder, wrapBuilder } from '@ohos.arkui.component'; + +@Builder +function MyBuilder(value: string, size: number) { + Text(value) + .fontSize(size) +} + +@Builder +function YourBuilder(value: string, size: number) { + Text(value) + .fontSize(size) + .fontColor(Color.Pink) +} + +const builderArr: WrappedBuilder<@Builder (p1: string, p2: number) => void>[] = [wrapBuilder(MyBuilder), wrapBuilder(YourBuilder)]; + + +@Entry +@Component +struct Index { + @Builder testBuilder() { + ForEach(builderArr, (item: WrappedBuilder<@Builder (p1: string, p2: number) => void>) => { + item.builder('Hello World', 30) + }) + } + + build() { + Row() { + Column() { + this.testBuilder() + } + .width('100%') + } + .height('100%') + } +} +``` + ## 引用传递 通过按引用传递的方式传入参数,会触发UI的刷新。 +**ArkTS 1.1:** ```ts class Tmp { paramA2: string = 'hello'; @@ -170,9 +278,42 @@ struct Parent{ } ``` +**ArkTS 1.2:** +```ts +import { WrappedBuilder, wrapBuilder } from '@ohos.arkui.component'; +import { Observed } from '@ohos.arkui.stateManagement'; + +@Observed +class Tmp { + paramA2: string = 'hello'; +} + +@Builder function overBuilder(param: () => Tmp) { + Column(){ + Text(`wrapBuildervalue:${param().paramA2}`) + } +} + +const wBuilder: WrappedBuilder<@Builder (param: () => Tmp) => void> = wrapBuilder(overBuilder); + +@Entry +@Component +struct Parent{ + @State label: Tmp = new Tmp(); + build(){ + Column(){ + wBuilder.builder(() => { return {paramA2: this.label.paramA2};}) + Button('Click me').onClick((e: ClickEvent) => { + this.label.paramA2 = 'ArkUI'; + }) + } + } +} +``` + ## 常见问题 -### 重复定义wrapBuilder失效 +### 重复定义wrapBuilder失效(ArkTS1.1) 在同一个自定义组件内,同一个wrapBuilder只能初始化一次。示例中builderObj通过wrapBuilder(MyBuilderFirst)初始化定义之后,再次对builderObj进行赋值wrapBuilder(MyBuilderSecond)不会生效。 @@ -216,4 +357,4 @@ struct Index { .height('100%') } } -``` \ No newline at end of file +``` -- Gitee