【鸿蒙开发Q&A】使用ForEach渲染List视图只显示第一个元素或显示不全

【问题描述】在使用ForEach循环渲染List视图时,只显示第一个元素或者显示不全。问题示例代码及效果图:

List显示不全.png

【问题分析】出现问题当然是先直奔最权威的官网ForEach使用文档,API说明提到:

在ForEach循环渲染过程中,系统会为每个数组元素生成一个唯一且持久的键值,用于标识对应的组件。当键值变化时,ArkUI框架会视为该数组元素已被替换或修改,并会基于新的键值创建一个新的组件。
ForEach提供了一个名为keyGenerator的参数,这是一个函数,开发者可以通过它自定义键值的生成规则。如果开发者没有定义keyGenerator函数,则ArkUI框架会使用默认的键值生成函数,即(item: Object, index: number) => { return index + '__' + JSON.stringify(item); }。
ArkUI框架对于ForEach的键值生成有一套特定的判断规则,这主要与itemGenerator函数和keyGenerator函数的第二个参数index有关。具体的键值生成规则判断逻辑如下图所示:


ForEach键值生成规则.png

其中的index即数组下标。也就是说,在使用ForEach时,要确保列表数据展示的完整性,就要确保每个item的键值是唯一的。结合ForEach构造函数:

  (arr: Array<any>, itemGenerator: (item: any, index: number) => void, keyGenerator?: (item: any, index: number) => string): ForEachAttribute;

可以发现,问题示例中没有声明itemGenerator中的index:number参数,所以每个元素的键值由keyGenerator函数返回值决定,而我的数据源中没有为每个元素的imageItem.id赋值,所以JSON.stringify(imageItem.id)返回的键值都是一样的,导致只显示一个数据:
问题分析图.png

【解决方法】根据问题分析中的ForEach键值生成规则,可以通过以下方式解决:

  1. 声明itemGenerator的index参数,但是不声明keyGenerator的index参数。这样会默认使用系统的键值生成函数,即(item: Object, index: number) => { return index + '__' + JSON.stringify(item); },确保元素唯一性:
    添加itemGenerator的index参数.png

    该方式最便捷,通用性也高,不过如果item的字段很多或内容很长,那默认生成的键值也会很大,影响性能。

  2. 声明itemGenerator和的keyGenerator的index参数,同时确保keyGenerator的函数返回值是唯一的:
    添加index参数确保keyGenerator函数返回值唯一.png
  3. 不声明itemGenerator的index参数,但声明keyGenerator的index参数,同时确保keyGenerator的函数返回值是唯一的:
    只声明keyGenerator的index参数.png
  4. 不声明itemGenerator和keyGenerator的index参数,但是要确保keyGenerator的函数返回值是唯一的:
    不声明index参数但是keyGenerator返回值唯一.png

【小结】以上四种解决方式已覆盖ForEach的键值生成规则,item内容较小可考虑使用第一种方式;其他根据实际情况使用另外三种,注意确保keyGenerator函数返回值的唯一性即可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容