• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# \@BuilderParam Decorator: @Builder Function Reference
2
3
4In certain circumstances, you may need to add a specific function, such as a click-to-jump action, to a custom component. However, embedding an event method directly inside of the component will add the function to all places where the component is imported. This is where the \@BuilderParam decorator comes into the picture. \@BuilderParam is used to decorate a custom component member variable of type reference to an \@Builder method. When initializing a custom component, you can assign a value to the variable, thereby adding the specific function to the custom component. This decorator can be used to declare an element of any UI description, similar to a slot placeholder.
5
6
7> **NOTE**
8>
9> Since API version 9, this decorator is supported in ArkTS widgets.
10
11
12## Rules of Use
13
14
15### Initializing \@BuilderParam Decorated Method
16
17An \@BuildParam decorated method can be initialized only by an \@Builder function reference.
18
19- Local initialization with the owning component's custom \@Builder function or a global \@Builder function reference
20
21  ```ts
22  @Builder function GlobalBuilder0() {}
23
24  @Component
25  struct Child {
26    @Builder doNothingBuilder() {};
27
28    @BuilderParam aBuilder0: () => void = this.doNothingBuilder;
29    @BuilderParam aBuilder1: () => void = GlobalBuilder0;
30    build(){}
31  }
32  ```
33
34- Initialization from the parent component
35
36  ```ts
37  @Component
38  struct Child {
39    @Builder componentBuilder() {
40      Text(`Parent builder `)
41    }
42
43    @BuilderParam aBuilder0: () => void = this.componentBuilder;
44
45    build() {
46      Column() {
47        this.aBuilder0()
48      }
49    }
50  }
51
52  @Entry
53  @Component
54  struct Parent {
55    @Builder componentBuilder() {
56      Text(`Parent builder `)
57    }
58
59    build() {
60      Column() {
61        Child({ aBuilder0: this.componentBuilder })
62      }
63    }
64  }
65  ```
66
67
68- **this** in the function body points to the correct object.
69
70  In the following example, when the **Parent** component calls **this.componentBuilder()**, **this.label** points to the owning component, that is, **Parent**. With **\@BuilderParam aBuilder0** passed to the **Child** component from **\@Builder componentBuilder()**, when the **Child** component calls **this.aBuilder0()**, **this.label** points to the label of the child component, that is, **Child**. For **\@BuilderParam aBuilder1**, when **this.componentBuilder** is passed to **aBuilder1**, **bind** is called to bind **this**. Therefore, **this.label** points to the label of the parent component.
71
72   >  **NOTE**
73   >
74   >  Exercise caution when using **bind** to change the context of function invoking, which may cause **this** to point to an incorrect object.
75
76  ```ts
77  @Component
78  struct Child {
79    @Builder componentBuilder() {
80      Text(`Child builder `)
81    }
82
83    label: string = `Child`
84    @BuilderParam aBuilder0: () => void = this.componentBuilder;
85    @BuilderParam aBuilder1: () => void = this.componentBuilder;
86
87    build() {
88      Column() {
89        this.aBuilder0()
90        this.aBuilder1()
91      }
92    }
93  }
94
95  @Entry
96  @Component
97  struct Parent {
98    label: string = `Parent`
99
100    @Builder componentBuilder() {
101      Text(`${this.label}`)
102    }
103
104    build() {
105      Column() {
106        this.componentBuilder()
107        Child({ aBuilder0: this.componentBuilder, aBuilder1: this.componentBuilder })
108      }
109    }
110  }
111  ```
112
113
114## Application Scenarios
115
116
117### Component Initialization Through Parameters
118
119An \@BuilderParam decorated method can be a method with or without parameters. Whether it contains parameters should match that of the assigned \@Builder method. The type of the \@BuilderParam decorated method must also match that of the assigned \@Builder method.
120
121
122```ts
123class GlobalBuilderParam {
124  label: string = ""
125}
126
127@Builder function GlobalBuilder1($$ : GlobalBuilderParam) {
128  Text($$.label)
129    .width(400)
130    .height(50)
131    .backgroundColor(Color.Blue)
132}
133
134@Component
135struct Child {
136  @Builder componentBuilder() {
137    Text(`Child builder `)
138  }
139
140  label: string = 'Child'
141  // Without parameters. The pointed componentBuilder is also without parameters.
142  @BuilderParam aBuilder0: () => void = this.componentBuilder;
143  // With parameters. The pointed GlobalBuilder1 is also with parameters.
144  @BuilderParam aBuilder1: ($$ : GlobalBuilderParam) => void = this.componentBuilder;
145
146  build() {
147    Column() {
148      this.aBuilder0()
149      this.aBuilder1({label: 'global Builder label' } )
150    }
151  }
152}
153
154@Entry
155@Component
156struct Parent {
157  label: string = 'Parent'
158
159  @Builder componentBuilder() {
160    Text(`${this.label}`)
161  }
162
163  build() {
164    Column() {
165      this.componentBuilder()
166      Child({ aBuilder0: this.componentBuilder, aBuilder1: GlobalBuilder1 })
167    }
168  }
169}
170```
171
172
173### Component Initialization Through Trailing Closure
174
175In a custom component, the \@BuilderParam decorated attribute can be initialized using a trailing closure. During initialization, the component name is followed by a pair of braces ({}) to form a trailing closure.
176
177> **NOTE**
178>
179> In this scenario, the custom component has one and only one \@BuilderParam decorated attribute.
180
181You can pass the content in the trailing closure to \@BuilderParam as an \@Builder decorated method. Example:
182
183
184```ts
185// xxx.ets
186class CustomContainerParam {
187  header: string = '';
188}
189@Component
190struct CustomContainer {
191  @Builder componentCloser() {
192    Text(`Custom closer `)
193  }
194
195  @Prop header: string = '';
196  @BuilderParam closer: () => void = this.componentCloser;
197
198  build() {
199    Column() {
200      Text(this.header)
201        .fontSize(30)
202      this.closer()
203    }
204  }
205}
206
207@Builder function specificParam(label1: string, label2: string) {
208  Column() {
209    Text(label1)
210      .fontSize(30)
211    Text(label2)
212      .fontSize(30)
213  }
214}
215
216@Entry
217@Component
218struct CustomContainerUser {
219  @State text: string = 'header';
220  param: CustomContainerParam = {
221    header: this.text
222  };
223
224  build() {
225    Column() {
226      // Create the CustomContainer component. During initialization, append a pair of braces ({}) to the component name to form a trailing closure.
227      // Used as the parameter passed to CustomContainer @BuilderParam closer: () => void.
228      CustomContainer(this.param) {
229        Column() {
230          specificParam('testA', 'testB')
231        }.backgroundColor(Color.Yellow)
232        .onClick(() => {
233          this.text = 'changeHeader';
234        })
235      }
236    }
237  }
238}
239```
240