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