数据懒加载LazyForEach

2023-12-24 19:52:09

????????LazyForEach从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。当在滚动容器中使用了LazyForEach,框架会根据滚动容器可视区域按需创建组件,当组件滑出可视区域外时,框架会进行组件销毁回收以降低内存占用。

1、接口描述

? ? ? ? 懒加载接口LazyFoEach如下:

LazyForEach(
    dataSource: IDataSource,             // 需要进行数据迭代的数据源
    itemGenerator: (item: any, index?: number) => void,  // 子组件生成函数
    keyGenerator?: (item: any, index?: number) => string // 键值生成函数
): void

? ? ? ? 参数说明:

参数名

参数类型

必填

参数描述

dataSource

IDataSource

LazyForEach数据源,需要开发者实现相关接口。

itemGenerator

(item: any, index?:number) => void

子组件生成函数,为数组中的每一个数据项创建一个子组件。

说明:

item是当前数据项,index是数据项索引值。

itemGenerator的函数体必须使用大括号{...}。itemGenerator每次迭代只能并且必须生成一个子组件。itemGenerator中可以使用if语句,但是必须保证if语句每个分支都会创建一个相同类型的子组件。itemGenerator中不允许使用ForEach和LazyForEach语句。

keyGenerator

(item: any, index?:number) => string

键值生成函数,用于给数据源中的每一个数据项生成唯一且固定的键值。当数据项在数组中的位置更改时,其键值不得更改,当数组中的数据项被新项替换时,被替换项的键值和新项的键值必须不同。键值生成器的功能是可选的,但是,为了使开发框架能够更好地识别数组更改,提高性能,建议提供。如将数组反向时,如果没有提供键值生成器,则LazyForEach中的所有节点都将重建。

说明:

item是当前数据项,index是数据项索引值。

数据源中的每一个数据项生成的键值不能重复。

2、IDataSource类型说明

? ? ? ? 该接口如下:?

interface IDataSource {
    totalCount(): number; // 获得数据总数
    getData(index: number): Object; // 获取索引值对应的数据
    registerDataChangeListener(listener: DataChangeListener): void; // 注册数据改变的监听器
    unregisterDataChangeListener(listener: DataChangeListener): void; // 注销数据改变的监听器
}

参数说明:?

接口声明

参数类型

说明

totalCount(): number

-

获得数据总数。

getData(index: number): any

number

获取索引值index对应的数据。

index:获取数据对应的索引值。

registerDataChangeListener(listener:DataChangeListener): void

DataChangeListener

注册数据改变的监听器。

listener:数据变化监听器

unregisterDataChangeListener(listener:DataChangeListener): void

DataChangeListener

注销数据改变的监听器。

listener:数据变化监听器

3、DataChangeListener类型说明

????????该接口如下:

interface DataChangeListener {
    onDataReloaded(): void; // 重新加载数据时调用
    onDataAdded(index: number): void; // 添加数据时调用
    onDataMoved(from: number, to: number): void; // 数据移动起始位置与数据移动目标位置交换时调用
    onDataDeleted(index: number): void; // 删除数据时调用
    onDataChanged(index: number): void; // 改变数据时调用
    onDataAdd(index: number): void; // 添加数据时调用
    onDataMove(from: number, to: number): void; // 数据移动起始位置与数据移动目标位置交换时调用
    onDataDelete(index: number): void; // 删除数据时调用
    onDataChange(index: number): void; // 改变数据时调用
}

? ? ? ? ?参数说明:

接口声明

参数类型

说明

onDataReloaded(): void

-

通知组件重新加载所有数据。

键值没有变化的数据项会使用原先的子组件,键值发生变化的会重建子组件。

onDataAdd(index: number): void8+

number

通知组件index的位置有数据添加。

index:数据添加位置的索引值。

onDataMove(from: number, to: number): void8+

from: number,

to: number

通知组件数据有移动。

from: 数据移动起始位置,to: 数据移动目标位置。

说明:

数据移动前后键值要保持不变,如果键值有变化,应使用删除数据和新增数据接口。

onDataDelete(index: number):void8+

number

通知组件删除index位置的数据并刷新LazyForEach的展示内容。

index:数据删除位置的索引值。

说明:

需要保证dataSource中的对应数据已经在调用onDataDelete前删除,否则页面渲染将出现未定义的行为。

onDataChange(index: number): void8+

number

通知组件index的位置有数据有变化。

index:数据变化位置的索引值。

onDataAdded(index: number):void(deprecated)

number

通知组件index的位置有数据添加。

从API 8开始,建议使用onDataAdd。

index:数据添加位置的索引值。

onDataMoved(from: number, to: number): void(deprecated)

from: number,

to: number

通知组件数据有移动。

从API 8开始,建议使用onDataMove。

from: 数据移动起始位置,to: 数据移动目标位置。

将from和to位置的数据进行交换。

说明:

数据移动前后键值要保持不变,如果键值有变化,应使用删除数据和新增数据接口。

onDataDeleted(index: number):void(deprecated)

number

通知组件删除index位置的数据并刷新LazyForEach的展示内容。

从API 8开始,建议使用onDataDelete。

index:数据删除位置的索引值。

onDataChanged(index: number): void(deprecated)

number

通知组件index的位置有数据有变化。

从API 8开始,建议使用onDataChange。

index:数据变化监听器。

  • LazyForEach必须在容器组件内使用,仅有List、Grid、Swiper以及WaterFlow组件支持数据懒加载(可配置cachedCount属性,即只加载可视部分以及其前后少量数据用于缓冲),其他组件仍然是一次性加载所有的数据。
  • LazyForEach在每次迭代中,必须创建且只允许创建一个子组件。
  • 生成的子组件必须是允许包含在LazyForEach父容器组件中的子组件。
  • 允许LazyForEach包含在if/else条件渲染语句中,也允许LazyForEach中出现if/else条件渲染语句。
  • 键值生成器必须针对每个数据生成唯一的值,如果键值相同,将导致键值相同的UI组件被框架忽略,从而无法在父容器内显示。
  • LazyForEach必须使用DataChangeListener对象来进行更新,第一个参数dataSource使用状态变量时,状态变量改变不会触发LazyForEach的UI刷新。
  • 为了高性能渲染,通过DataChangeListener对象的onDataChange方法来更新UI时,需要生成不同于原来的键值来触发组件刷新。

4、键值生成规则

????????在LazyForEach循环渲染过程中,系统会为每个item生成一个唯一且持久的键值,用于标识对应的组件。当这个键值变化时,ArkUI框架将视为该数组元素已被替换或修改,并会基于新的键值创建一个新的组件。

????????LazyForEach提供了一个名为keyGenerator的参数,这是一个函数,开发者可以通过它自定义键值的生成规则。如果开发者没有定义keyGenerator函数,则ArkUI框架会使用默认的键值生成函数,即(item: any, index: number) => { return viewId + '-' + index.toString(); }, viewId在编译器转换过程中生成,同一个LazyForEach组件内其viewId是一致的。

5、组件创建规则

????????在确定键值生成规则后,LazyForEach的第二个参数itemGenerator函数会根据键值生成规则为数据源的每个数组项创建组件。组件的创建包括两种情况:LazyForEach首次渲染LazyForEach非首次渲染

5.1、首次渲染

?

文章来源:https://blog.csdn.net/www586089/article/details/135184226
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。