1# LazyForEach 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @maorh--> 5<!--Designer: @keerecles--> 6<!--Tester: @TerryTsao--> 7<!--Adviser: @HelloCrease--> 8 9> **说明** 10> 11> 本模块首批接口从API version 7开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 12 13开发者指南见:[LazyForEach开发者指南](../../../ui/state-management/arkts-rendering-control-lazyforeach.md)。 14在大量子组件的的场景下,LazyForEach与缓存列表项、动态预加载、组件复用等方法配合使用,可以进一步提升滑动帧率并降低应用内存占用。最佳实践请参考[优化长列表加载慢丢帧问题](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-best-practices-long-list)。 15 16## 接口 17 18LazyForEach(dataSource: IDataSource, itemGenerator: (item: any, index: number) => void, keyGenerator?: (item: any, index: number) => string) 19 20LazyForEach从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。当在滚动容器中使用了LazyForEach,框架会根据滚动容器可视区域按需创建组件,当组件滑出可视区域外时,框架会进行组件销毁回收以降低内存占用。 21 22**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 23 24**系统能力:** SystemCapability.ArkUI.ArkUI.Full 25 26**参数:** 27 28| 参数名 | 类型 | 必填 | 说明 | 29| ------------- | --------------------------------------------------------- | ---- | ------------------------------------------------------------ | 30| dataSource | [IDataSource](#idatasource) | 是 | LazyForEach数据源,需要开发者实现相关接口。 | 31| itemGenerator | (item: any, index: number) => void | 是 | 子组件生成函数,为数组中的每一个数据项创建一个子组件。<br/>**说明:**<br/>- item是当前数据项(可选),index是数据项索引值(可选)。<br/>- itemGenerator的函数体必须使用大括号{...}。<br />- itemGenerator每次迭代只能并且必须生成一个子组件。<br />- itemGenerator中可以使用if语句,但是必须保证if语句每个分支都会创建一个相同类型的子组件。 | 32| keyGenerator | (item: any, index: number) => string | 否 | 键值生成函数,用于给数据源中的每一个数据项生成唯一且固定的键值。修改数据源中的一个数据项若不影响其生成的键值,则对应组件不会被更新,否则此处组件就会被重建更新。`keyGenerator`参数是可选的,但是,为了使开发框架能够更好地识别数组更改并正确更新组件,建议提供。<br/>**说明:**<br/>- item是当前数据项(可选),index是数据项索引值(可选)。<br/>- 数据源中的每一个数据项生成的键值不能重复。<br/>- `keyGenerator`缺省时,使用默认的键值生成函数,即`(item: Object, index: number) => { return viewId + '-' + index.toString(); }`,生成键值仅受索引值index影响(viewId在编译器转换过程中生成,同一个LazyForEach组件内的viewId一致)。 | 33 34> **说明:** 35> 36> 应避免在`keyGenerator`和`itemGenerator`函数中执行耗时操作,以此来减少应用滑动时卡顿丢帧问题,最佳实践请参考[主线程耗时操作优化-循环渲染](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-time-optimization-of-the-main-thread#section4551193714439)。例如,不推荐使用JSON.stringify函数。在复杂的业务场景中,使用JSON.stringify会对item对象进行序列化,该过程会消耗大量时间与计算资源,从而降低页面性能,最佳实践请参考[懒加载优化性能-键值生成规则](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-lazyforeach-optimization#section68711519072)。 37 38## IDataSource 39 40**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 41 42**系统能力:** SystemCapability.ArkUI.ArkUI.Full 43 44### totalCount 45 46totalCount(): number 47 48获得数据总数。 49 50**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 51 52**系统能力:** SystemCapability.ArkUI.ArkUI.Full 53 54**返回值:** 55 56| 类型 | 说明 | 57| ------------------- | --------- | 58| number | 获得数据总数,由数据源决定实际大小。 | 59 60### getData 61 62getData(index: number): any 63 64获取索引值index对应的数据。 65 66**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 67 68**系统能力:** SystemCapability.ArkUI.ArkUI.Full 69 70**参数:** 71 72| 参数名 | 类型 | 必填 | 说明 | 73| ------ | ------ | ---- | -------------------- | 74| index | number | 是 | 获取数据对应的索引值。取值范围是[0, 数据源长度-1]。 | 75 76**返回值:** 77 78| 类型 | 说明 | 79| ------------------- | --------- | 80| any | 获取索引值index对应的数据,由数据源决定具体类型。 | 81 82> **说明:** 83> 84> 应避免在`getData`函数中执行执行耗时操作,以此来减少应用滑动时卡顿丢帧问题,最佳实践请参考[主线程耗时操作优化-循环渲染](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-time-optimization-of-the-main-thread#section4551193714439)。 85 86### registerDataChangeListener 87 88registerDataChangeListener(listener: DataChangeListener): void 89 90注册数据改变的监听器。 91 92**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 93 94**系统能力:** SystemCapability.ArkUI.ArkUI.Full 95 96**参数:** 97 98| 参数名 | 类型 | 必填 | 说明 | 99| -------- | ------------------------------------------- | ---- | -------------- | 100| listener | [DataChangeListener](#datachangelistener) | 是 | 数据变化监听器。 | 101 102### unregisterDataChangeListener 103 104unregisterDataChangeListener(listener: DataChangeListener): void 105 106注销数据改变的监听器。 107 108**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 109 110**系统能力:** SystemCapability.ArkUI.ArkUI.Full 111 112**参数:** 113 114| 参数名 | 类型 | 必填 | 说明 | 115| -------- | ------------------------------------------- | ---- | -------------- | 116| listener | [DataChangeListener](#datachangelistener) | 是 | 数据变化监听器。 | 117 118## DataChangeListener 119 120数据变化监听器。 121 122> **说明:** 123> 124> DataChangeListener除onDatasetChange以外的方法中,当参数包含index且值为负数时,会默认用0来替换。onDatasetChange中,当单个DataOperation参数包含index且值在数据源索引范围之外(DataAddOperation中index可以等于数据源长度),则对应DataOperation不会生效。 125 126**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 127 128**系统能力:** SystemCapability.ArkUI.ArkUI.Full 129 130### onDataReloaded 131 132onDataReloaded(): void 133 134通知组件重新加载所有数据。键值没有变化的数据项会使用原先的子组件,键值发生变化的会重建子组件。重新加载数据完成后调用。 135 136**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 137 138**系统能力:** SystemCapability.ArkUI.ArkUI.Full 139 140### onDataAdded<sup>(deprecated)</sup> 141 142onDataAdded(index: number): void 143 144通知组件index的位置有数据添加。添加数据完成后调用。 145 146> 从API version 8开始,建议使用[onDataAdd](#ondataadd8)。 147 148**系统能力:** SystemCapability.ArkUI.ArkUI.Full 149 150**参数:** 151 152| 参数名 | 类型 | 必填 | 说明 | 153| ------ | ------ | ---- | -------------------- | 154| index | number | 是 | 数据添加位置的索引值。取值范围是[0, 数据源长度-1]。 | 155 156### onDataMoved<sup>(deprecated)</sup> 157 158onDataMoved(from: number, to: number): void 159 160通知组件数据有移动。将from和to位置的数据进行交换。 161 162> 从API version 8开始,建议使用[onDataMove](#ondatamove8)。 163 164> **说明:** 165> 166> 数据移动前后键值要保持不变,如果键值有变化,应使用删除数据和新增数据接口。数据移动起始位置与数据移动目标位置交换完成后调用。 167 168**系统能力:** SystemCapability.ArkUI.ArkUI.Full 169 170**参数:** 171 172| 参数名 | 类型 | 必填 | 说明 | 173| ------ | ------ | ---- | ---------------- | 174| from | number | 是 | 数据移动起始位置。取值范围是[0, 数据源长度-1]。 | 175| to | number | 是 | 数据移动目标位置。取值范围是[0, 数据源长度-1]。 | 176 177### onDataDeleted<sup>(deprecated)</sup> 178 179onDataDeleted(index: number): void 180 181通知组件删除index位置的数据并刷新LazyForEach的展示内容。删除数据完成后调用。 182 183> 从API version 8开始,建议使用[onDataDelete](#ondatadelete8)。 184 185**系统能力:** SystemCapability.ArkUI.ArkUI.Full 186 187**参数:** 188 189| 参数名 | 类型 | 必填 | 说明 | 190| ------ | ------ | ---- | -------------------- | 191| index | number | 是 | 数据删除位置的索引值。取值范围是[0, 数据源长度-1]。 | 192 193### onDataChanged<sup>(deprecated)</sup> 194 195onDataChanged(index: number): void 196 197通知组件index的位置有数据变化。改变数据完成后调用。 198 199> 从API version 8开始,建议使用[onDataChange](#ondatachange8)。 200 201**系统能力:** SystemCapability.ArkUI.ArkUI.Full 202 203**参数:** 204 205| 参数名 | 类型 | 必填 | 说明 | 206| ------ | ------ | ---- | -------------- | 207| index | number | 是 | 数据变化监听器。取值范围是[0, 数据源长度-1]。 | 208 209### onDataAdd<sup>8+</sup> 210 211onDataAdd(index: number): void 212 213通知组件index的位置有数据添加。添加数据完成后调用 214 215**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。 216 217**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 218 219**系统能力:** SystemCapability.ArkUI.ArkUI.Full 220 221**参数:** 222 223| 参数名 | 类型 | 必填 | 说明 | 224| ------ | ------ | ---- | -------------- | 225| index | number | 是 | 数据添加位置的索引值。取值范围是[0, 数据源长度-1]。 | 226 227### onDataMove<sup>8+</sup> 228 229onDataMove(from: number, to: number): void 230 231通知组件数据有移动。将from和to位置的数据进行交换。数据移动起始位置与数据移动目标位置交换完成后调用。 232 233> **说明:** 234> 235> 数据移动前后键值要保持不变,如果键值有变化,应使用删除数据和新增数据接口。 236 237**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 238 239**系统能力:** SystemCapability.ArkUI.ArkUI.Full 240 241**参数:** 242 243| 参数名 | 类型 | 必填 | 说明 | 244| ------ | ------ | ---- | ---------------- | 245| from | number | 是 | 数据移动起始位置。取值范围是[0, 数据源长度-1]。 | 246| to | number | 是 | 数据移动目标位置。取值范围是[0, 数据源长度-1]。 | 247 248### onDataDelete<sup>8+</sup> 249 250onDataDelete(index: number): void 251 252通知组件删除index位置的数据并刷新LazyForEach的展示内容。删除数据完成后调用。 253 254> **说明:** 255> 256> 需要保证dataSource中的对应数据已经在调用onDataDelete前删除,否则页面渲染将出现未定义的行为。 257 258**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 259 260**系统能力:** SystemCapability.ArkUI.ArkUI.Full 261 262**参数:** 263 264| 参数名 | 类型 | 必填 | 说明 | 265| ------ | ------ | ---- | -------------------- | 266| index | number | 是 | 数据删除位置的索引值。取值范围是[0, 数据源长度-1]。 | 267 268### onDataChange<sup>8+</sup> 269 270onDataChange(index: number): void 271 272通知组件index的位置有数据有变化。改变数据完成后调用。 273 274**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 275 276**系统能力:** SystemCapability.ArkUI.ArkUI.Full 277 278**参数:** 279 280| 参数名 | 类型 | 必填 | 说明 | 281| ------ | ------ | ---- | -------------------- | 282| index | number | 是 | 数据变化位置的索引值。取值范围是[0, 数据源长度-1]。 | 283 284### onDatasetChange<sup>12+</sup> 285 286onDatasetChange(dataOperations: DataOperation[]): void 287 288进行批量的数据处理后,调用onDatasetChange接口通知组件按照dataOperations刷新组件。 289 290> **说明:** 291> 292> onDatasetChange接口不能与其他DataChangeListener的更新接口混用。例如,在同一个LazyForEach中,调用过onDataAdd接口后,不能再调用onDatasetChange接口;反之,调用过onDatasetChange接口后,也不能调用onDataAdd等其他更新接口。页面中不同LazyForEach之间互不影响。在同一个onDatasetChange批量处理数据时,如果多个DataOperation操作同一个index,只有第一个DataOperation生效。 293**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 294 295**系统能力:** SystemCapability.ArkUI.ArkUI.Full 296 297**参数:** 298 299| 参数名 | 类型 | 必填 | 说明 | 300| -------------- | ------------------- | ---- | ------------------ | 301| dataOperations | [DataOperation](#dataoperation12)[] | 是 | 一次处理数据的操作。 | 302 303## DataOperation<sup>12+</sup> 304 305> **说明** 306> 307> 本模块首批接口从API version 12开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 308 309**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 310 311**系统能力:** SystemCapability.ArkUI.ArkUI.Full 312 313### DataAddOperation 314 315添加数据操作。 316 317**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 318 319**系统能力:** SystemCapability.ArkUI.ArkUI.Full 320 321**参数:** 322 323| 参数名 | 类型 | 必填 | 说明 | 324| ------ | ------------------------- | ---- | -------------------- | 325| type | [DataOperationType](#dataoperationtype枚举说明).ADD | 是 | 数据添加类型。 | 326| index | number | 是 | 插入数据索引值。取值范围是[0, 数据源长度-1]。 | 327| count | number | 否 | 插入数量,默认为1。 | 328| key | string \| Array\<string\> | 否 | 为插入的数据分配键值,默认使用原键值。 | 329 330### DataDeleteOperation 331 332删除数据操作。 333 334**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 335 336**系统能力:** SystemCapability.ArkUI.ArkUI.Full 337 338**参数:** 339 340| 参数名 | 类型 | 必填 | 说明 | 341| ------ | ------------------------- | ---- | -------------------- | 342| type | [DataOperationType](#dataoperationtype枚举说明).DELETE | 是 | 数据删除类型。 | 343| index | number | 是 | 起始删除位置索引值。取值范围是[0, 数据源长度-1]。| 344| count | number | 否 | 删除数据数量,默认为1。 | 345 346### DataChangeOperation 347 348改变数据操作。 349 350**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 351 352**系统能力:** SystemCapability.ArkUI.ArkUI.Full 353 354**参数:** 355 356| 参数名 | 类型 | 必填 | 说明 | 357| ------ | ------------------------- | ---- | -------------------- | 358| type | [DataOperationType](#dataoperationtype枚举说明).CHANGE | 是 | 数据改变类型。 | 359| index | number | 是 | 改变的数据的索引值。取值范围是[0, 数据源长度-1]。| 360| key | string | 否 | 为改变的数据分配新的键值,默认使用原键值。 | 361 362### DataMoveOperation 363 364移动数据操作。 365 366**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 367 368**系统能力:** SystemCapability.ArkUI.ArkUI.Full 369 370**参数:** 371 372| 参数名 | 类型 | 必填 | 说明 | 373| ------ | ------------------------- | ---- | -------------------- | 374| type | [DataOperationType](#dataoperationtype枚举说明).MOVE | 是 | 数据移动类型。 | 375| index | [MoveIndex](#moveindex12) | 是 | 移动位置。取值范围是[0, 数据源长度-1]。| 376| key | string | 否 | 为被移动的数据分配新的键值,默认使用原键值。 | 377 378### DataExchangeOperation 379 380交换数据操作。 381 382**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 383 384**系统能力:** SystemCapability.ArkUI.ArkUI.Full 385 386**参数:** 387 388| 参数名 | 类型 | 必填 | 说明 | 389| ------ | -------------------------- | ---- | ---------------------------- | 390| type | [DataOperationType](#dataoperationtype枚举说明).EXCHANGE | 是 | 数据交换类型。 | 391| index | [ExchangeIndex](#exchangeindex12) | 是 | 交换位置。取值范围是[0, 数据源长度-1]。| 392| key | [ExchangeKey](#exchangekey12) | 否 | 分配新的键值,默认使用原键值。 | 393 394### DataReloadOperation 395 396重载所有数据操作。当onDatasetChange含有DataOperationType.RELOAD操作时,其余操作全部失效,框架会自己调用keyGenerator进行键值比对。 397 398**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 399 400**系统能力:** SystemCapability.ArkUI.ArkUI.Full 401 402**参数:** 403 404| 参数名 | 类型 | 必填 | 说明 | 405| ------ | ------------------------ | ---- | ---------------- | 406| type | [DataOperationType](#dataoperationtype枚举说明).RELOAD | 是 | 数据全部重载类型。 | 407 408### DataOperationType枚举说明 409 410枚举类型,数据操作说明。 411 412**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 413 414**系统能力:** SystemCapability.ArkUI.ArkUI.Full 415 416| 名称 | 值 | 说明 | 417| ------ | ------------------- | -------------------- | 418| ADD | add | 数据添加。 | 419| DELETE | delete | 数据删除。 | 420| CHANGE | change | 数据改变。 | 421| MOVE | move | 数据移动。 | 422| EXCHANGE | exchange | 数据交换。 | 423| RELOAD | reload | 全部数据重载。 | 424 425## MoveIndex<sup>12+</sup> 426 427**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 428 429**系统能力:** SystemCapability.ArkUI.ArkUI.Full 430 431**参数:** 432 433| 参数名 | 类型 | 必填 | 说明 | 434| ------ | --------------- | ---- | ------- | 435| from | number | 是 | 起始移动位置。取值范围是[0, 数据源长度-1]。| 436| to | number | 是 | 目的移动位置。取值范围是[0, 数据源长度-1]。| 437 438## ExchangeIndex<sup>12+</sup> 439 440**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 441 442**系统能力:** SystemCapability.ArkUI.ArkUI.Full 443 444**参数:** 445 446| 参数名 | 类型 | 必填 | 说明 | 447| ------ | --------------- | ---- | ------- | 448| start | number | 是 | 第一个交换位置。取值范围是[0, 数据源长度-1]。| 449| end | number | 是 | 第二个交换位置。取值范围是[0, 数据源长度-1]。| 450 451## ExchangeKey<sup>12+</sup> 452 453**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 454 455**系统能力:** SystemCapability.ArkUI.ArkUI.Full 456 457**参数:** 458 459| 参数名 | 类型 | 必填 | 说明 | 460| ------ | --------------- | ---- | ------- | 461| start | string | 是 | 为第一个交换的位置分配新的键值,默认使用原键值。 | 462| end | string | 是 | 为第二个交换的位置分配新的键值,默认使用原键值。 |