• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# \@BuilderParam: @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    @BuilderParam aBuilder0: () => void;
40
41    build() {
42      Column() {
43        this.aBuilder0()
44      }
45    }
46  }
47
48  @Entry
49  @Component
50  struct Parent {
51    @Builder componentBuilder() {
52      Text(`Parent builder `)
53    }
54
55    build() {
56      Column() {
57        Child({ aBuilder0: this.componentBuilder })
58      }
59    }
60  }
61  ```
62
63
64- **this** in the function body points to the correct object.
65
66  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**.
67
68   >  **NOTE**
69   >
70   >  Exercise caution when using **bind** to change the context of function invoking, which may cause **this** to point to an incorrect object.
71
72  ```ts
73  @Component
74  struct Child {
75    label: string = `Child`
76    @BuilderParam aBuilder0: () => void;
77
78    build() {
79      Column() {
80        this.aBuilder0()
81      }
82    }
83  }
84
85  @Entry
86  @Component
87  struct Parent {
88    label: string = `Parent`
89
90    @Builder componentBuilder() {
91      Text(`${this.label}`)
92    }
93
94    build() {
95      Column() {
96        this.componentBuilder()
97        Child({ aBuilder0: this.componentBuilder })
98      }
99    }
100  }
101  ```
102
103
104## Application Scenarios
105
106
107### Component Initialization Through Parameters
108
109An \@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.
110
111
112```ts
113@Builder function GlobalBuilder1($$ : {label: string }) {
114  Text($$.label)
115    .width(400)
116    .height(50)
117    .backgroundColor(Color.Blue)
118}
119
120@Component
121struct Child {
122  label: string = 'Child'
123  // Without parameters. The pointed componentBuilder is also without parameters.
124  @BuilderParam aBuilder0: () => void;
125  // With parameters. The pointed GlobalBuilder1 is also with parameters.
126  @BuilderParam aBuilder1: ($$ : { label : string}) => void;
127
128  build() {
129    Column() {
130      this.aBuilder0()
131      this.aBuilder1({label: 'global Builder label' } )
132    }
133  }
134}
135
136@Entry
137@Component
138struct Parent {
139  label: string = 'Parent'
140
141  @Builder componentBuilder() {
142    Text(`${this.label}`)
143  }
144
145  build() {
146    Column() {
147      this.componentBuilder()
148      Child({ aBuilder0: this.componentBuilder, aBuilder1: GlobalBuilder1 })
149    }
150  }
151}
152```
153
154
155### Example of Component Initialization Through Trailing Closure
156
157In 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.
158
159> **NOTE**
160> In this scenario, the custom component has one and only one \@BuilderParam decorated attribute.
161
162You can pass the content in the trailing closure to \@BuilderParam as an \@Builder decorated method. Example:
163
164
165```ts
166// xxx.ets
167@Component
168struct CustomContainer {
169  @Prop header: string;
170  @BuilderParam closer: () => void
171
172  build() {
173    Column() {
174      Text(this.header)
175        .fontSize(30)
176      this.closer()
177    }
178  }
179}
180
181@Builder function specificParam(label1: string, label2: string) {
182  Column() {
183    Text(label1)
184      .fontSize(30)
185    Text(label2)
186      .fontSize(30)
187  }
188}
189
190@Entry
191@Component
192struct CustomContainerUser {
193  @State text: string = 'header';
194
195  build() {
196    Column() {
197      // Create the CustomContainer component. During initialization, append a pair of braces ({}) to the component name to form a trailing closure.
198      // Used as the parameter passed to CustomContainer @BuilderParam closer: () => void.
199      CustomContainer({ header: this.text }) {
200        Column() {
201          specificParam('testA', 'testB')
202        }.backgroundColor(Color.Yellow)
203        .onClick(() => {
204          this.text = 'changeHeader';
205        })
206      }
207    }
208  }
209}
210```
211