1# Repeat 2 3> **NOTE** 4> 5> The initial APIs of this module are supported since API version 12. Newly added APIs will be marked with a superscript to indicate their earliest API version. 6 7**Repeat** is used to perform repeated rendering based on array data. Generally, it is used together with container components. 8 9This document provides API parameter descriptions. For details about the component descriptions and usage guidelines, see [Repeat: Reusable Repeated Rendering](../../../ui/state-management/arkts-new-rendering-control-repeat.md). 10 11## APIs 12 13### Repeat: \<T\>(arr: Array\<T\>) 14 15**Widget capability**: This API can be used in ArkTS widgets since API version 12. 16 17**Atomic service API**: This API can be used in atomic services since API version 12. 18 19**System capability**: SystemCapability.ArkUI.ArkUI.Full 20 21**Parameters** 22 23| Name| Type | Mandatory| Description | 24| ------ | ---------- | -------- | -------- | 25| arr | Array\<T\> | Yes| Data source, which is an array of the **Array\<T>** type. You can determine the data types.| 26 27**Example** 28```ts 29// arr is an array of the Array<string> type, which is used as the data source for Repeat. 30Repeat<string>(this.arr) 31``` 32 33### Repeat: \<T\>(arr: RepeatArray\<T\>)<sup>18+</sup> 34 35> **NOTE** 36> 37> Data sources of the RepeatArray type are supported since API version 18. 38 39**Widget capability**: This API can be used in ArkTS widgets since API version 18. 40 41**Atomic service API**: This API can be used in atomic services since API version 18. 42 43**System capability**: SystemCapability.ArkUI.ArkUI.Full 44 45**Parameters** 46 47| Name| Type | Mandatory| Description | 48| ------ | ---------- | -------- | -------- | 49| arr | [RepeatArray\<T\>](#repeatarrayt18) | Yes| Data source, which is an array of the **RepeatArray\<T>** type. You can determine the data types.| 50 51## Properties 52 53**Widget capability**: This API can be used in ArkTS widgets since API version 12. 54 55**Atomic service API**: This API can be used in atomic services since API version 12. 56 57**System capability**: SystemCapability.ArkUI.ArkUI.Full 58 59### each 60 61each(itemGenerator: (repeatItem: RepeatItem\<T\>) => void) 62 63Component generator. When none of the **.template()** types match the return value of **.templateId()**, **.each()** will be used to process data items. 64 65> **NOTE** 66> 67> The **each** property is mandatory. If it is omitted, runtime errors will occur. 68> The **itemGenerator** parameter is of the **RepeatItem** type, which combines **item** and **index**. Do not destructure **RepeatItem**. 69 70**Widget capability**: This API can be used in ArkTS widgets since API version 12. 71 72**Atomic service API**: This API can be used in atomic services since API version 12. 73 74**System capability**: SystemCapability.ArkUI.ArkUI.Full 75 76**Parameters** 77 78| Name| Type | Mandatory| Description| 79| ------ | ---------- | -------- | -------- | 80| repeatItem | [RepeatItem](#repeatitemt)\<T\> | Yes| Repeat data item.| 81 82**Example** 83```ts 84// Create a Text component for each item in the arr array of the Array<string> type. 85Repeat<string>(this.arr) 86 .each((obj: RepeatItem<string>) => { Text(obj.item) }) 87``` 88 89### key 90 91key(keyGenerator: (item: T, index: number) => string) 92 93Key generator. 94 95**Widget capability**: This API can be used in ArkTS widgets since API version 12. 96 97**Atomic service API**: This API can be used in atomic services since API version 12. 98 99**System capability**: SystemCapability.ArkUI.ArkUI.Full 100 101**Parameters** 102 103| Name| Type | Mandatory| Description | 104| ------ | ---------- | -------- | -------- | 105| item | T | Yes| Data item in the **arr** array.| 106| index | number | Yes| Index of the data item in the **arr** array.| 107 108**Example** 109```ts 110// Create a Text component for each item in the arr array of the Array<string> type. 111// Use the string value as its key. 112Repeat<string>(this.arr) 113 .each((obj: RepeatItem<string>) => { Text(obj.item) }) 114 .key((obj: string) => obj) 115``` 116 117### virtualScroll 118 119virtualScroll(virtualScrollOptions?: VirtualScrollOptions) 120 121Enables virtual scrolling for **Repeat**. 122 123**Atomic service API**: This API can be used in atomic services since API version 12. 124 125**System capability**: SystemCapability.ArkUI.ArkUI.Full 126 127**Parameters** 128 129| Name| Type | Mandatory| Description | 130| ------ | ---------- | -------- | -------- | 131| virtualScrollOptions | [VirtualScrollOptions](#virtualscrolloptions) | No| Virtual scrolling configuration.| 132 133**Example** 134```ts 135// Create a Text component for each item in the arr array of the Array<string> type. 136// Use Repeat in a List container component with virtual scrolling enabled. 137List() { 138 Repeat<string>(this.arr) 139 .each((obj: RepeatItem<string>) => { ListItem() { Text(obj.item) }}) 140 .virtualScroll() 141} 142``` 143 144### template 145 146template(type: string, itemBuilder: RepeatItemBuilder\<T\>, templateOptions?: TemplateOptions) 147 148Renders the corresponding template child component based on the template type. 149 150**Atomic service API**: This API can be used in atomic services since API version 12. 151 152**System capability**: SystemCapability.ArkUI.ArkUI.Full 153 154**Parameters** 155 156| Name| Type | Mandatory| Description | 157| ------ | ---------- | -------- | -------- | 158| type | string | Yes| Current template type.| 159| itemBuilder | [RepeatItemBuilder](#repeatitembuildert)\<T\> | Yes| Component generator.| 160| templateOptions | [TemplateOptions](#templateoptions) | No| Current template configuration.| 161 162**Example** 163```ts 164// arr is an array of the Array<string> type. 165// Use Repeat in a List container component with virtual scrolling enabled. 166// Define a reusable template temp for generating Text components. 167List() { 168 Repeat<string>(this.arr) 169 .each((obj: RepeatItem<string>) => {}) 170 .virtualScroll() 171 .template('temp', (obj: RepeatItem<string>) => { ListItem() { Text(obj.item) }}) 172} 173``` 174 175### templateId 176 177templateId(typedFunc: TemplateTypedFunc\<T\>) 178 179Assigns a template type for this data item. 180 181**Atomic service API**: This API can be used in atomic services since API version 12. 182 183**System capability**: SystemCapability.ArkUI.ArkUI.Full 184 185**Parameters** 186 187| Name| Type | Mandatory| Description | 188| ------ | ---------- | -------- | -------- | 189| typedFunc | [TemplateTypedFunc](#templatetypedfunct)\<T\> | Yes| Function that generates a template type for each data item.| 190 191**Example** 192```ts 193// arr is an array of the Array<string> type. 194// Use Repeat in a List container component with virtual scrolling enabled. 195// Define a reusable template temp for generating Text components. 196// Use the temp template for all data items. 197List() { 198 Repeat<string>(this.arr) 199 .each((obj: RepeatItem<string>) => {}) 200 .virtualScroll() 201 .template('temp', (obj: RepeatItem<string>) => { ListItem() { Text(obj.item) }}) 202 .templateId((item: string, index: number) => { return 'temp' }) 203} 204``` 205 206## RepeatArray\<T\><sup>18+</sup> 207 208type RepeatArray\<T\> = Array\<T\> | ReadonlyArray\<T\> | Readonly\<Array\<T\>\> 209 210Defines a union type for **Repeat** data source parameters. 211 212**Widget capability**: This API can be used in ArkTS widgets since API version 18. 213 214**Atomic service API**: This API can be used in atomic services since API version 18. 215 216**System capability**: SystemCapability.ArkUI.ArkUI.Full 217 218| Type | Description | 219| -------- | -------- | 220| Array\<T\> | Regular array type.| 221| ReadonlyArray\<T\> | Read-only array type, where the array object cannot be modified.| 222| Readonly\<Array\<T\>> | Read-only array type, where the array object cannot be modified.| 223 224## RepeatItem\<T\> 225 226**Widget capability**: This API can be used in ArkTS widgets since API version 12. 227 228**Atomic service API**: This API can be used in atomic services since API version 12. 229 230**System capability**: SystemCapability.ArkUI.ArkUI.Full 231 232| Name| Type | Mandatory| Description | 233| ------ | ------ | ---- | -------------------------------------------- | 234| item | T | Yes | Each data item in the **arr** array. **T** indicates the data type passed in.| 235| index | number | Yes | Index corresponding to the current data item. | 236 237## VirtualScrollOptions 238 239**Atomic service API**: This API can be used in atomic services since API version 12. 240 241**System capability**: SystemCapability.ArkUI.ArkUI.Full 242 243| Name | Type | Mandatory| Description | 244| ---------- | ------ | ---- | ------------------------------------------------------------ | 245| totalCount | number | No | Total number of data items to load, which may not equal the data source length.<br>Value range: [0, +��).<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 246| reusable<sup>18+</sup> | boolean | No | Whether to enable the reuse feature. The value **true** means to enable the reuse feature, and **false** means the opposite.<br>Default value: **true**.<br>**Atomic service API**: This API can be used in atomic services since API version 18.| 247| onLazyLoading<sup>19+</sup> | (index: number) => void | No | Function to load data on demand for a given index.<br>**Atomic service API**: This API can be used in atomic services since API version 19.| 248| onTotalCount<sup>19+</sup> | () => number | No | Function to dynamically obtain the total number of items, which may not equal the data source length. Prioritize this function over **totalCount**. If both **totalCount** and **onTotalCount** are set, **totalCount** is ignored.<br>Value range: [0, +��).<br>**Atomic service API**: This API can be used in atomic services since API version 19.| 249 250### totalCount: Length of the Data to Be Loaded 251 252**totalCount** indicates the length of the data to be loaded, which is the length of the original array by default and can be greater than the number of loaded data items. **arr.length** represents the length of the data source. The processing rules for **totalCount** are as follows: 253 254- When **totalCount** is omitted or set to a non-natural number, the value of **totalCount** is **arr.length**, and the list scrolls normally. 255- When the value of **totalCount** is greater that or equal to **0** and smaller than the value of **arr.length**, only data within the range of [0, *totalCount* - 1] is rendered. 256- When the value of **totalCount** is greater than the value of **arr.length**, data in the range of [0, *totalCount* - 1] will be rendered. The scrollbar style changes based on the value of **totalCount**. 257 258> **NOTE** 259> 260> When the value of **totalCount** is greater than the value of **arr.length**, during the scrolling of the parent component container, the application needs to ensure that subsequent data is requested when the list is about to scroll to the end of the data source. You need to handle error scenarios (such as network delays) for data requests until all data sources are loaded; otherwise, scrolling exceptions may occur during list scrolling. For solutions, see [The totalCount Value Is Greater Than the Length of Data Source](../../../ui/state-management/arkts-new-rendering-control-repeat.md#the-totalcount-value-is-greater-than-the-length-of-data-source). 261 262### onLazyLoading<sup>19+</sup>: Precise Lazy Loading 263 264**onLazyLoading** is supported since API version 19 and is intended for use in lazy loading scenarios. You can implement a custom method to write data to a specified index in the data source. The processing rules for **onLazyLoading** are as follows: 265 266- Before reading the data corresponding to an index in the data source, **Repeat** checks whether data exists at that index. 267- If no data exists but the **onLazyLoading** method is implemented, **Repeat** calls this method. 268- In the **onLazyLoading** method, data should be written to the index specified by **Repeat** in the format of **arr[index] = ...**. In addition, array operations except **[]** are not allowed, and elements except the specified index cannot be written. Otherwise, the system throws an exception. 269- After the **onLazyLoading** method is executed, if no data exists in the specified index, rendering exceptions will occur. 270 271> **NOTE** 272> 273> - Whenever possible, use **onLazyLoading** together with **onTotalCount** instead of **totalCount**. 274> - **onLazyLoading** is recommended in scenarios where the expected data length is greater than the actual source length. 275> - Avoid using the **onLazyLoading** method to execute time-consuming operations. If data loading takes a long time, you are advised to create a placeholder for the data in the **onLazyLoading** method and then create an asynchronous task to load the data. 276> - When **onLazyLoading** is used and **onTotalCount** is set to **arr.length + 1**, data can be loaded infinitely. In this scenario, you need to provide the initial data required for the first screen display and set **cachedCount** to a value greater than 0 for the parent container component. Otherwise, rendering exceptions will occur. Avoid using the **onLazyLoading** method together with the loop mode of **Swipe**. Otherwise, staying at **index = 0** will trigger continuous **onLazyLoading** calls. In addition, you need to pay attention to the memory usage to avoid excessive memory consumption caused by continuous data loading. 277 278### onTotalCount<sup>19+</sup>: Calculating the Expected Data Length 279 280**onTotalCount** is supported since API version 19 and is intended for use in lazy loading scenarios. You can implement a custom method that returns the expected array length. The return value must be a natural number and may not be equal to the actual data source length **arr.length**. The processing rules for **onTotalCount** are as follows: 281 282- When the return value is a non-natural number, **arr.length** is used as the return value and the list scrolls normally. 283- When the return value is greater that or equal to **0** and smaller than the value of **arr.length**, only data within the range of [0, *return value* - 1] is rendered. 284- When the return value is greater than **arr.length**, the data within the range of [0, *return value* - 1] is rendered. The scrollbar style changes based on the return value. 285 286> **NOTE** 287> 288> - Unlike **totalCount**, **onTotalCount** can be proactively called by **Repeat** to update the expected data length when necessary. 289> - Use either **totalCount** or **onTotalCount**, not both. If neither is set, the default value of **arr.length** is used. If both are set, **totalCount** is ignored. 290> - When the return value of **onTotalCount** is greater than the value of **arr.length**, you are advised to use **onLazyLoading** to implement lazy loading. 291 292### Example 293 294```ts 295// Create a Text component for each item in the arr array. Use Repeat in a List container component with virtual scrolling enabled. 296// Set the total number of data items to the length of the data source and enable component reuse. 297List() { 298 Repeat<string>(this.arr) 299 .each((obj: RepeatItem<string>) => { ListItem() { Text(obj.item) }}) 300 .virtualScroll( { totalCount: this.arr.length, reusable: true } ) 301} 302 303// Assume that the total number of items is 100, and 3 items are needed for the initial screen rendering. 304// The initial array provides the first 3 items (arr = ['No.0', 'No.1', 'No.2']), and lazy loading is enabled. 305List() { 306 Repeat<string>(this.arr) 307 .each((obj: RepeatItem<string>) => { ListItem() { Text(obj.item) }}) 308 .virtualScroll({ 309 onTotalCount: () => { return 100; }, 310 onLazyLoading: (index: number) => { this.arr[index] = `No.${index}`; } 311 }) 312} 313``` 314 315## RepeatItemBuilder\<T\> 316 317type RepeatItemBuilder\<T\> = (repeatItem: RepeatItem\<T\>) => void 318 319**Atomic service API**: This API can be used in atomic services since API version 12. 320 321**System capability**: SystemCapability.ArkUI.ArkUI.Full 322 323**Parameters** 324 325| Name | Type | Mandatory | Description | 326| ---------- | ------------- | --------------------------------------- | --------------------------------------- | 327| repeatItem | [RepeatItem](#repeatitemt)\<T\> | Yes| State variable that combines **item** and **index**.| 328 329## TemplateOptions 330 331**Atomic service API**: This API can be used in atomic services since API version 12. 332 333**System capability**: SystemCapability.ArkUI.ArkUI.Full 334 335| Name | Type | Mandatory| Description | 336| ----------- | ------ | ---- | ------------------------------------------------------------ | 337| cachedCount | number | No | Maximum number of child component nodes that can be cached in the cache pool of the current template. <br>Value range: [0, +��). <br>Default value: sum of the number of onscreen and preloaded nodes. <br>When the number of onscreen and preloaded nodes increases, the value of **cachedCount** will increase accordingly. Note that the value of **cachedCount** does not decrease.| 338 339When **cachedCount** is set to the maximum number of nodes displayed on the screen for the current template, **Repeat** achieves maximum reuse efficiency. However, when no nodes of the current template are on the screen, the cache pool will not be released, and application memory usage will increase. You need to manage this based on specific scenarios. 340 341- If **cachedCount** is not specified, the framework calculates the value of **cachedCount** for each template based on the sum of the number of onscreen and preloaded nodes. When the number of onscreen and preloaded nodes increases, the value of **cachedCount** will increase accordingly. Note that the value of **cachedCount** does not decrease. 342- When explicitly specifying **cachedCount**, you are advised to set it equal to the number of onscreen nodes. Yet, setting **cachedCount** to less than 2 is not advised. Doing so may lead to the creation of new nodes during rapid scrolling, which could result in performance degradation. 343 344> **NOTE** 345> 346> The **.cachedCount()** attribute of the scrolling container component and the **cachedCount** parameter of the **.template()** method of **Repeat** are used to balance performance and memory, but their meanings are different. 347> - **.cachedCount()** in scrollable container components (for example, **List** and **Grid**): indicates the preloaded nodes outside the visible range. These nodes exist in the component tree but are not visible. The container components render these off-screen nodes for performance benefits. However, **Repeat** treats these nodes as visible. 348> - **.cachedCount()** in **.template()**: indicates nodes that are treated as invisible by **Repeat**. These nodes are idle and are temporarily stored in the framework. You can update these nodes as required to implement reuse. 349 350**Example** 351```ts 352// Create a Text component for each item in the arr array. Use Repeat in a List container component with virtual scrolling enabled. 353// Define a reusable template temp for generating Text components. Use the temp template for all data items. 354// Set the maximum cache count for the temp template to 2. 355List() { 356 Repeat<string>(this.arr) 357 .each((obj: RepeatItem<string>) => {}) 358 .virtualScroll() 359 .template('temp', (obj: RepeatItem<string>) => { ListItem() { Text(obj.item) }}, { cachedCount: 2 }) 360 .templateId((item: string, index: number) => { return 'temp' }) 361} 362``` 363 364## TemplateTypedFunc\<T\> 365 366type TemplateTypedFunc\<T\> = (item: T, index: number) => string 367 368**Atomic service API**: This API can be used in atomic services since API version 12. 369 370**System capability**: SystemCapability.ArkUI.ArkUI.Full 371 372**Parameters** 373 374| Name| Type | Mandatory| Description | 375| ------ | ------ | ---- | -------------------------------------------- | 376| item | T | Yes | Each data item in the **arr** array. **T** indicates the data type passed in.| 377| index | number | Yes | Index corresponding to the current data item. | 378