• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Restrictions and Extensions
2
3## Restrictions on Using ArkTS in Generators
4
5ArkTS has the following restrictions on generators:
6
7- Expressions can be used only in character strings (${expression}), **if/else** statements, **ForEach** parameters, and component parameters.
8
9- No expressions should cause any application state variables (that is, variables decorated by **@State**, **@Link**, and **@Prop**) to change. Otherwise, undefined and potentially unstable framework behavior may occur.
10
11- The generator function cannot contain local variables.
12
13None of the above restrictions applies to anonymous function implementations of event methods (such as **onClick**).
14
15## Two-Way Binding of Variables
16
17ArkTS supports two-way binding through **$$**, which is usually used for variables whose state values change frequently.
18
19- **$$** supports variables of primitive types and variables decorated by **@State**, **@Link**, or **@Prop**.
20- **$$** supports only the **show** parameter of the **[bindPopup](../reference/arkui-ts/ts-universal-attributes-popup.md)** attribute method, the **checked** attribute of the **[\<Radio>](../reference/arkui-ts/ts-basic-components-radio.md)** component, and the **refreshing** parameter of the **[\<Refresh>](../reference/arkui-ts/ts-container-refresh.md)** component.
21- When the variable bound to **$$** changes, only the current component is rendered, which improves the rendering speed.
22
23```ts
24// xxx.ets
25@Entry
26@Component
27struct bindPopupPage {
28  @State customPopup: boolean = false
29
30  build() {
31    Column() {
32      Button('Popup')
33        .margin(20)
34        .onClick(() => {
35          this.customPopup = !this.customPopup
36        })
37        .bindPopup($$this.customPopup, {
38          message: "showPopup"
39        })
40    }
41  }
42}
43```
44
45![popup](figures/popup.gif)
46
47## Restrictions on Data Type Declarations of State Variables
48
491. The data types of state variables decorated by state decorators must be explicitly declared. They cannot be declared as **any** or **Date**.
50
51    Example:
52
53    ```ts
54    // xxx.ets
55    @Entry
56    @Component
57    struct DatePickerExample {
58      // Incorrect: @State isLunar: any = false
59      @State isLunar: boolean = false
60      // Incorrect: @State selectedDate: Date = new Date('2021-08-08')
61      private selectedDate: Date = new Date('2021-08-08')
62
63      build() {
64        Column() {
65          Button('Switch Calendar')
66            .margin({ top: 30 })
67            .onClick(() => {
68              this.isLunar = !this.isLunar
69            })
70          DatePicker({
71            start: new Date('1970-1-1'),
72            end: new Date('2100-1-1'),
73            selected: this.selectedDate
74          })
75            .lunar(this.isLunar)
76            .onChange((value: DatePickerResult) => {
77              this.selectedDate.setFullYear(value.year, value.month, value.day)
78              console.info('select current date is: ' + JSON.stringify(value))
79            })
80
81        }.width('100%')
82      }
83    }
84    ```
85
86    ![datePicker](../../application-dev/reference/arkui-ts/figures/datePicker.gif)
87
882. The data type declaration of the **@State**, **@Provide**, **@Link**, or **@Consume** decorated state variables can consist of only one of the primitive data types or reference data types.
89
90    The **Length**, **ResourceStr**, and **ResourceColor** types are combinations of primitive data types or reference data types. Therefore, they cannot be used by the aforementioned types of state variables.
91    For details about the definitions of **Length**, **ResourceStr**, and **ResourceColor**, see [Types](../../application-dev/reference/arkui-ts/ts-types.md).
92
93    Example:
94
95    ```ts
96    // xxx.ets
97    @Entry
98    @Component
99    struct IndexPage {
100      // Incorrect: @State message: string | Resource = 'Hello World'
101      @State message: string = 'Hello World'
102      // Incorrect: @State message: ResourceStr = $r('app.string.hello')
103      @State resourceStr: Resource = $r('app.string.hello')
104
105      build() {
106        Row() {
107          Column() {
108            Text(`${this.message}`)
109              .fontSize(50)
110              .fontWeight(FontWeight.Bold)
111          }
112          .width('100%')
113        }
114        .height('100%')
115      }
116    }
117    ```
118
119    ![hello](figures/hello.PNG)
120
121## Initialization Rules and Restrictions of Custom Components' Member Variables
122
123The member variables of a component can be initialized in either of the following ways:
124
125- Local initialization:
126
127  ```ts
128  @State counter: Counter = new Counter()
129  ```
130- Initialization using constructor parameters:
131
132  ```ts
133  MyComponent({counter: $myCounter})
134  ```
135
136The allowed method depends on the decorator of the state variable, as described in the following table.
137
138| Decorator       | Local Initialization| Initialization Using Constructor Parameters|
139| ------------ | ----- | ----------- |
140| @State       | Mandatory   | Optional         |
141| @Prop        | Forbidden   | Mandatory         |
142| @Link        | Forbidden   | Mandatory         |
143| @StorageLink | Mandatory   | Forbidden         |
144| @StorageProp | Mandatory   | Forbidden         |
145| @LocalStorageLink | Mandatory   | Forbidden         |
146| @LocalStorageProp | Mandatory   | Forbidden         |
147| @Provide     | Mandatory   | Optional         |
148| @Consume     | Forbidden   | Forbidden         |
149| @ObjectLink  | Forbidden   | Mandatory         |
150| Normal member variable      | Recommended   | Optional         |
151
152As indicated by the preceding table:
153
154- The **@State** decorated variables must be initialized locally. Their initial values can be overwritten by the constructor parameters.
155
156- The **@Prop** and **@Link** decorated variables must be initialized only by constructor parameters.
157
158Comply with the following rules when using constructors to initialize member variables:
159
160| **From the Variable in the Parent Component (Right) to the Variable in the Child Component (Below)**| **regular** | **@State** | **@Link** | **@Prop** | **@Provide** | **@Consume** | **@ObjectLink** |
161|---------------------------------|----------------------------|------------|-----------|-----------|--------------|--------------|------------------|
162| **regular**                    | Supported                        | Supported        | Supported       | Supported       | Not supported           | Not supported           | Supported              |
163| **@State**                     | Supported                        | Supported        | Supported       | Supported       | Supported          | Supported          | Supported              |
164| **@Link**                      | Not supported                         | Supported (1)     | Supported (1)    | Supported (1)    | Supported (1)       | Supported (1)       | Supported (1)           |
165| **@Prop**                      | Supported                        | Supported        | Supported       | Supported       | Supported          | Supported          | Supported              |
166| **@Provide**                   | Supported                        | Supported        | Supported       | Supported       | Supported          | Supported          | Supported              |
167| **@Consume**                   | Not supported                         | Not supported         | Not supported        | Not supported        | Not supported           | Not supported           | Not supported               |
168| **@ObjectLink**                | Not supported                         | Not supported     | Not supported        | Not supported        | Not supported           | Not supported           | Not supported               |
169
170| **From the Variable in the Parent Component (Right) to the Variable in the Child Component (Below)**| **@StorageLink** | **@StorageProp** | **@LocalStorageLink** | **@LocalStorageProp** |
171|------------------|------------------|------------------|-----------------------|------------------------|
172| **regular**                   | Supported              | Not supported               | Not supported                    | Not supported             |
173| **@State**                    | Supported              | Supported              | Supported                   | Supported                    |
174| **@Link**                     | Supported (1)           | Supported (1)           | Supported (1)                | Supported (1)                 |
175| **@Prop**                     | Supported              | Supported              | Supported                   | Supported                    |
176| **@Provide**                  | Supported              | Supported              | Supported                   | Supported                    |
177| **@Consume**                  | Not supported            | Not supported             | Not supported                 | Not supported                  |
178| **@ObjectLink**               | Not supported            | Not supported             | Not supported                 | Not supported                  |
179
180> **NOTE**
181>
182> **Supported (1)**: The dollar sign ($) must be used, for example, **this.$varA**.
183>
184> **regular**: refers to a regular variable that is not decorated by any decorator.
185
186As indicated by the preceding tables:
187
188- The **@ObjectLink** decorated variable cannot be directly initialized from a decorated variable in the parent component. The source of the parent component must be an array item or object attribute decorated by **@State**, **@Link**, **@Provide**, **@Consume**, or **@ObjectLink**.
189
190- The regular variables of the parent component can be used to initialize the **@State** variable of the child component, but cannot be used to initialize the **@Link**, **@Consume**, and **@ObjectLink** variables.
191
192- The **@State** variable of the parent component can be used to initialize the **@Prop**, **@Link** (through **$**), or regular variables of the child component, but cannot be used to initialize the **@Consume** variable.
193
194- The **@Link** variable of the parent component cannot be used to initialize the **@Consume** and **@ObjectLink** variables of the child component.
195
196- The **@Prop** variable of the parent component cannot be used to initialize the **@Consume** and **@ObjectLink** variables of the child component.
197
198- **@StorageLink**, **@StorageProp**, **@LocalStorageLink**, and **@LocalStorageProp** variables cannot be initialized from the parent component.
199
200- In addition to the preceding rules, the TypeScript strong type rules need to be followed.
201
202Example:
203```ts
204@Entry
205@Component
206struct Parent {
207  message: string = "Hello World"
208  build() {
209    Column() {
210      Child({
211        stateMessage: this.message,
212        /* ArkTS:ERROR The regular property 'message' cannot be assigned
213           to the @Link property 'linkMessage'.*/
214        linkMessage: this.$message
215      })
216    }
217    .width('100%')
218  }
219}
220
221@Component
222struct Child {
223  @State stateMessage: string = "Hello World"
224  @Link linkMessage: string
225  build() {
226    Column() {
227      Text(this.stateMessage)
228        .fontSize(50)
229        .fontWeight(FontWeight.Bold)
230    }
231    .width('100%')
232  }
233}
234```
235