• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# @Link
2
3
4Two-way binding can be established between the @Link decorated variable and the @State decorated variable of the parent component. The @Link data has the following features:
5
6
7- Support for multiple types: The value of the @Link decorated variable can be of the same type as the @State decorated variable; that is, the value can be of the following types: class, number, string, boolean, or arrays of these types.
8
9- Private: Data is accessed only within the component.
10
11- Single data source: The variable of the parent component for initializing the @Link decorated variable must be the @State decorated variable.
12
13- Two-way binding: When a child component changes the @Link decorated variable, the @State decorated variable of its parent component is also changed.
14
15- Support for initialization with the variable reference passed to the @Link decorated variable: When creating a new instance of the component, you must use the naming parameter to initialize all @Link decorated variables. The @Link decorated variable can be initialized by using the reference of the @State or @Link decorated variable. Wherein, the @State decorated variable can be referenced using the  ` '$' `  operator.
16
17
18> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
19>
20> The @Link decorated variable cannot be initialized within the component.
21
22
23## Simple Type Example
24
25
26```
27@Entry
28@Component
29struct Player {
30    @State isPlaying: boolean = false
31    build() {
32        Column() {
33            PlayButton({buttonPlaying: $isPlaying})
34            Text(`Player is ${this.isPlaying? '':'not'} playing`)
35        }
36    }
37}
38
39@Component
40struct PlayButton {
41    @Link buttonPlaying: boolean
42    build() {
43        Column() {
44            Button() {
45                Image(this.buttonPlaying? 'play.png' : 'pause.png')
46            }.onClick(() => {
47                this.buttonPlaying = !this.buttonPlaying
48            })
49        }
50    }
51}
52```
53
54The @Link semantics are derived from the  ` '$' `  operator. In other words,  ` $isPlaying `  is the two-way binding of the internal state  ` this.isPlaying ` . When you click **PlayButton**, the **\<Image>** and **\<Text>** components of **PlayButton** are refreshed at the same time.
55
56
57## Complex Type Example
58
59
60```
61@Entry
62@Component
63struct Parent {
64    @State arr: number[] = [1, 2, 3]
65    build() {
66        Column() {
67            Child({items: $arr})
68            ForEach(this.arr,
69                item => Text(`${item}`),
70                item => item.toString())
71        }
72    }
73}
74
75@Component
76struct Child {
77    @Link items: number[]
78    build() {
79        Column() {
80            Button() {
81                Text('Button1: push')
82            }.onClick(() => {
83                this.items.push(100)
84            })
85            Button() {
86                Text('Button2: replace whole item')
87            }.onClick(() => {
88                this.items = [100, 200, 300]
89            })
90        }
91    }
92}
93```
94
95In the example above, click **Button1** and **Button2** to change the list of text items displayed in the parent component.
96
97
98## Example of Using @Link, @State, and @Prop Together
99
100
101```
102@Entry
103@Component
104struct ParentView {
105    @State counter: number = 0
106    build() {
107        Column() {
108            ChildA({counterVal: this.counter})  // pass by value
109            ChildB({counterRef: $counter})      // $ creates a Reference that can be bound to counterRef
110        }
111    }
112}
113
114@Component
115struct ChildA {
116    @Prop counterVal: number
117    build() {
118        Button() {
119            Text(`ChildA: (${this.counterVal}) + 1`)
120        }.onClick(() => {this.counterVal+= 1})
121    }
122}
123
124@Component
125struct ChildB {
126    @Link counterRef: number
127    build() {
128        Button() {
129            Text(`ChildB: (${this.counterRef}) + 1`)
130        }.onClick(() => {this.counterRef+= 1})
131    }
132}
133```
134
135In the preceding example, ParentView contains two child components: ChildA and ChildB. They are initialized by the state variable counter of ParentView.
136
137- ChildB uses @Link to establish two-way state binding. When the value of the counterRef state variable is changed in ChildB, the change is synchronized to ParentView and ChildA.
138
139- ChildA uses @Prop to establish one-way state binding from ParentView to itself. When ChildA changes the state, it is re-rendered, but the change is not updated to ParentView or ChildB.
140