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