1# !! Syntax: Two-Way Binding 2In state management V1, [$$](./arkts-two-way-sync.md) is used for two-way binding of built-in components. 3In state management V2, the **!!** syntactic sugar is used to implement two-way binding of components in a unified manner. 4 5 6>**NOTE** 7> 8>The **!!** syntax is supported since API version 12. 9> 10 11## Overview 12 13**!!** is a syntactic sugar used to implement two-way binding of components in initialization of \@Param and \@Event of the child components. The \@Event method name must be declared as "$" + \@Param attribute name. For details, see [Use Scenarios](#use-scenarios). 14 15- If the parent component uses **!!**, the change of the parent component will be synchronized to the child component, and vice versa. 16- If the parent component does not use **!!**, the change of the parent component is unidirectional. 17 18 19## Constraints 20**!!** does not support multi-layer parent-child component transfer. 21 22 23## Use Scenarios 24 25### Two-Way Binding Between Custom Components 261. Construct the **Star** child component in the **Index** component, bind the value in the parent and child components bidirectionally, and initialize **@Param value** and **@Event $value** of the child component. 27- The two-way binding syntactic sugar can be considered as: 28 29 ``` 30 Star({ value: this.value, $value: (val: number) => { this.value = val }}) 31 ``` 322. Click the button in the **Index** component to change the value, and **Text** in both the parent component **Index** and child component **Star** will be updated. 333. Click the button in the child component **Star** to invoke **this.$value(10)**, and **Text** in both the parent component **Index** and child component **Star** will be updated. 34 35```ts 36@Entry 37@ComponentV2 38struct Index { 39 @Local value: number = 0; 40 41 build() { 42 Column() { 43 Text(`${this.value}`) 44 Button(`change value`).onClick(() => { 45 this.value++; 46 }) 47 Star({ value: this.value!! }) 48 } 49 } 50} 51 52 53@ComponentV2 54struct Star { 55 @Param value: number = 0; 56 @Event $value: (val: number) => void = (val: number) => {}; 57 58 build() { 59 Column() { 60 Text(`${this.value}`) 61 Button(`change value `).onClick(() => { 62 this.$value(10); 63 }) 64 } 65 } 66} 67``` 68 69 70### Two-Way Binding Between Built-in Component Parameters 71 72The **!!** operator provides a TypeScript variable by-reference to a built-in component so that the variable value and the internal state of that component are kept in sync. Add this operator after the variable name, for example, **isShow!!**. 73 74What the internal state is depends on the component. For example, the **isShow** parameter of the [bindMenu](../reference/apis-arkui/arkui-ts/ts-universal-attributes-menu.md) component. 75 76#### Rules of Use 77 78- Currently, **!!** supports two-way binding of the following parameters of the basic types, that is, the parameters can synchronize the current menu or popup state. In addition, **!!** supports two-way binding of variables of the basic types as well. When a variable is decorated by [\@Local](arkts-new-local.md) of V2 or [\@State](arkts-state.md) of V1, the change of the variable value triggers the UI re-render. 79 80 | Attribute | Supported Parameter| Initial API Version| 81 | ------------------------------------------------------------ | --------------- | ----------- | 82 | [bindMenu](../reference/apis-arkui/arkui-ts/ts-universal-attributes-menu.md#bindmenu11) | isShow | 13 | 83 | [bindContextMenu](../reference/apis-arkui/arkui-ts/ts-universal-attributes-menu.md#bindcontextmenu12) | isShown | 13 | 84 | [bindPopup](../reference/apis-arkui/arkui-ts/ts-universal-attributes-popup.md#bindpopup) | show | 13 | 85 86- When the [\@Local](arkts-new-local.md) decorated variable bound to **!!** changes, the UI is rendered synchronously. 87 88 89#### Example 90 91Two-way binding of the **isShow** parameter of the **bindMenu** API: 92 93```ts 94@Entry 95@ComponentV2 96struct BindMenuInterface { 97 @Local isShow: boolean = false; 98 99 build() { 100 Column() { 101 Row() { 102 Text('click show Menu') 103 .bindMenu(this.isShow!!, // Two-way binding. 104 [ 105 { 106 value: 'Menu1', 107 action: () => { 108 console.info('handle Menu1 click'); 109 } 110 }, 111 { 112 value: 'Menu2', 113 action: () => { 114 console.info('handle Menu2 click'); 115 } 116 }, 117 ]) 118 }.height('50%') 119 Text("isShow: " + this.isShow).fontSize(18).fontColor(Color.Red) 120 Row() { 121 Button("Click") 122 .onClick(() => { 123 this.isShow = true; 124 }) 125 .width(100) 126 .fontSize(20) 127 .margin(10) 128 } 129 }.width('100%') 130 } 131} 132``` 133 134 135