LazyForEach常见使用问题

       

目录

1、渲染结果非预期

2、重新渲染时图片闪烁

3、@ObjectLink属性变化UI未更新


        上篇文章中我们介绍了LazyForEach的基本使用,展示了如何使用LazyForEach构造一个列表,并演示数据的添加、删除、修改如何与LazyForEach配合并正确的更新UI。本篇将介绍使用LazyForEach的时候会遇到的一些常见问题。

1、渲染结果非预期

        代码如下:

import { SimpleStringDataSource } from './base/LazyForeach';

@Entry
@Component
struct LazyForEachDemo3Page {
  private data: SimpleStringDataSource = new SimpleStringDataSource();

  aboutToAppear() {
    for (let i = 0; i <= 20; i++) {
      this.data.pushData(`Hello ${i}`)
    }
  }

  build() {
    List({ space: 3 }) {
      LazyForEach(this.data, (item: string, index: number) => {
        ListItem() {
          Row() {
            Text(item).fontSize(50)
              .onAppear(() => {
                console.info("appear:" + item)
              })
          }.margin({ left: 10, right: 10 })
        }
        .onClick(() => {
          // 点击删除子组件
          this.data.deleteData(index);
          // 重置所有子组件的index索引
          // this.data.reloadData();
        })
      }, (item: string, index: number) => item + index.toString())
    }.cachedCount(5).width('100%').height('100%')
  }
}

        运行结果如下:

        

        当我们多次点击子组件时,会发现删除的并不一定是我们点击的那个子组件。原因是当我们删除了某一个子组件后,位于该子组件对应的数据项之后的各数据项,其index均应减1,但实际上后续的数据项对应的子组件仍然使用的是最初分配的index,其itemGenerator中的index并没有发生变化,所以删除结果和预期不符。如何修复呢?把注释的那行代码打开即可(在删除一个数据项后调用reloadData方法,重建后面的数据项,以达到更新index索引的目的)。

2、重新渲染时图片闪烁

        如下代码只更新文本时,会引起图片的更新,看上去发生了闪烁:

import { StringData } from './base/LazyData';
import { ComplexDataSource } from './base/LazyForeach';

@Entry
@Component
struct LazyRenderDemo4Page {
  private moved: number[] = [];
  private data: ComplexDataSource = new ComplexDataSource();

  aboutToAppear() {
    for (let i = 0; i <= 20; i++) {
      this.data.pushData(new StringData(`Hello ${i}`, $r('app.media.girl1')));
    }
  }

  build() {
    List({ space: 3 }) {
      LazyForEach(this.data, (item: StringData, index: number) => {
        ListItem() {
          Column() {
            Text(item.message).fontSize(50)
              .onAppear(() => {
                console.info("appear:" + item.message)
              })
            Image(item.imgSrc)
              .width(500)
              .height(200)
          }.margin({ left: 10, right: 10 })
        }
        .onClick(() => {
          item.message += '00';
          this.data.reloadData();
        })
      }, (item: StringData, index: number) => JSON.stringify(item))
    }.cachedCount(5).width('100%').height('100%')
  }
}

         运行效果如下:

更新文本时,图片闪烁

        在我们点击ListItem子组件时,我们只改变了数据项的message属性,但是LazyForEach的刷新机制会导致整个ListItem被重建。由于Image组件是异步刷新,所以视觉上图片会发生闪烁。为了解决这种情况我们应该使用@ObjectLink和@Observed去单独刷新使用了item.message的Text组件(代码里还修改了键值对的生成规则)。

import { StringData } from './base/LazyData';
import { ComplexDataSource } from './base/LazyForeach';

@Entry
@Component
struct LazyRenderDemo4Page {
  private moved: number[] = [];
  private data: ComplexDataSource = new ComplexDataSource();

  aboutToAppear() {
    for (let i = 0; i <= 20; i++) {
      this.data.pushData(new StringData(`Hello ${i}`, $r('app.media.girl1')));
    }
  }

  build() {
    List({ space: 3 }) {
      LazyForEach(this.data, (item: StringData, index: number) => {
        ListItem() {
          LazyDemo4ChildComponent({data: item})
        }
        .onClick(() => {
          item.message += '00';
          this.data.reloadData();
        })
      }, (item: StringData, index: number) => {
        //key不变,此时只更新相关item的数据
        return index.toString()
      })
    }.cachedCount(5).width('100%').height('100%')
  }
}

@Component
struct LazyDemo4ChildComponent {
  @ObjectLink data: StringData
  build() {
    Column() {
      Text(this.data.message).fontSize(50)
        .onAppear(() => {
          console.info("appear:" + this.data.message)
        })
      Image(this.data.imgSrc)
        .width(500)
        .height(200)
    }.margin({ left: 10, right: 10 })
  }
}

        修复后运行效果如下:

只更新文本,图片不闪烁

3、@ObjectLink属性变化UI未更新

import { NestedString, StringDataV2 } from './base/LazyData';
import { MyDataSource } from './base/LazyForeach';

@Entry
@Component
struct LazyRenderDemo5Page {
  @State data: MyDataSource<StringDataV2> = new MyDataSource<StringDataV2>();

  aboutToAppear() {
    for (let i = 0; i <= 20; i++) {
      this.data.pushData(new StringDataV2(new NestedString(`Hello ${i}`)));
    }
  }

  build() {
    List({ space: 3 }) {
      LazyForEach(this.data, (item: StringDataV2, index: number) => {
        ListItem() {
          LazyRenderDemo5ChildComponent({data: item})
        }
        .onClick(() => {
          // item.message.message += '0';
          item.message = new NestedString(item.message.message + '0');
        })
      }, (item: StringDataV2, index: number) => item.toString() + index.toString())
    }.cachedCount(5).width('100%').width('100%')
  }
}

@Component
struct LazyRenderDemo5ChildComponent {
  @ObjectLink data: StringDataV2
  build() {
    Row() {
      Text(this.data.message.message).fontSize(50)
        .onAppear(() => {
          console.info("appear:" + this.data.message.message)
        })
    }.margin({ left: 10, right: 10 })
  }
}



@Observed
export class StringDataV2 {
  message: NestedString;
  constructor(message: NestedString) {
    this.message = message;
  }
}

@Observed
export class NestedString {
  message: string;
  constructor(message: string) {
    this.message = message;
  }
}

        @ObjectLink装饰的成员变量仅能监听到其子属性的变化,再深入嵌套的属性便无法观测到了,因此我们只能改变它的子属性去通知对应组件重新渲染,具体请查看@ObjectLink与@Observed的详细使用方法和限制条件。

        如何修复呢?既然不支持2层嵌套属性变化,那就在第一场嵌套属性变化上作文章,修复代码如下:

onClick(() => {
  item.message = new NestedString(item.message.message + '0');
})

        比较简单,就是修改第一层嵌套属性的值(@ObjectLink能监听到该层的变化)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/273514.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【kafka消息里会有乱序消费的情况吗?如果有,是怎么解决的?】

文章目录 什么是消息乱序消费了&#xff1f;顺序生产&#xff0c;顺序存储&#xff0c;顺序消费如何解决乱序数据库乐观锁是怎么解决这个乱序问题吗 保证消息顺序消费两种方案固定分区方案乐观锁实现方案 前几天刷着视频看见评论区有大佬问了这个问题&#xff1a;你们的kafka消…

策略模式(组件协作)

策略模式&#xff08;组件协作&#xff09; 链接&#xff1a;策略模式实例代码 注解 目的 正常情况下&#xff0c;一个类/对象中会包含其所有可能会使用的内外方法&#xff0c;但是一般情况下&#xff0c;这些常使用的类都是由不同的父类继承、组合得来的&#xff0c;来实现…

《软件需求分析报告》

第1章 序言 第2章 引言 2.1 项目概述 2.2 编写目的 2.3 文档约定 2.4 预期读者及阅读建议 第3章 技术要求 3.1 软件开发要求 第4章 项目建设内容 第5章 系统安全需求 5.1 物理设计安全 5.2 系统安全设计 5.3 网络安全设计 5.4 应用安全设计 5.5 对用户安全管理 …

创建servlet的三种方式

目录 ​编辑 1.实现Servlet接口的方式 2.继承GenericServlet抽象类的方式 3.继承HttpServlet的方式 1.实现Servlet接口的方式 因为是实现 Servlet 接口&#xff0c;所以我们需要实现接口里的方法。 import javax.servlet.*; import javax.servlet.annotation.WebServlet;…

DS八大排序之归并排序和计数排序

前言 前几期我们详细介绍了插入排序&#xff08;直接插入排序和希尔排序&#xff09;、选择排序&#xff08;直接选择和堆排序&#xff09;、交换排序&#xff08;冒泡排序和快速排序&#xff09;。并对快排的各个版本做了详细的介绍&#xff0c;本期我们来介绍把最后两个即外…

k8s面试之——简述网络模型

kubernetes网络模型是kubernetes集群中管理容器网络通信的一种机制&#xff0c;用于实现pod间、pod与外部网络间的通信和互联&#xff0c;并提供了多种网络插件和配置选项来满足不同应用场景下的需求。kubernetes网络模型可以分为一下几个部分&#xff1a; 1. pod网络模型 在…

经典文献阅读之--OccNeRF(基于神经辐射场的自监督多相机占用预测)

0. 简介 作为基于视觉感知的基本任务&#xff0c;3D占据预测重建了周围环境的3D结构。它为自动驾驶规划和导航提供了详细信息。然而&#xff0c;大多数现有方法严重依赖于激光雷达点云来生成占据地面真实性&#xff0c;而这在基于视觉的系统中是不可用的。之前我们介绍了《经典…

cephfs cap机制介绍

一、Cap&#xff1a;概述 cap是文件系统层面的&#xff0c;包括元数据、数据操作。cap 和mds分布式锁是对应的cap是MDS分配给client对inode的操作能力权限。不同的客户端&#xff0c;或者同一客户端不同时刻&#xff0c;对同一inode持有cap可能是不同的•作用&#xff1a;MDS通…

学习笔记13——Spring整合Mybatis、junit、AOP、事务

学习笔记系列开头惯例发布一些寻亲消息 链接&#xff1a;https://baobeihuijia.com/bbhj/ Mybatis - Spring&#xff08;使用第三方包new一个对象bean&#xff09; 原始的Mybatis与数据库交互【通过sqlmapconfig来配置和连接】 初始化SqlSessionFactory获得连接获取数据层接口…

Python pandas 操作 excel 详解

文章目录 1 概述1.1 pandas 和 openpyxl 区别1.2 Series 和 DataFrame 2 常用操作2.1 创建 Excel&#xff1a;to_excel()2.2 读取 Excel&#xff1a;read_excel()2.2.1 header&#xff1a;标题的行索引2.2.2 index_col&#xff1a;索引列2.2.3 dtype&#xff1a;数据类型2.2.4 …

ansible 备忘清单(一)

笔者&#xff1a; 把以前的手写笔记电子化吧&#xff0c;顺便当作复习。 基础命令 命令 参数 备注 ansible --version 查看版本号 ansible-doc --help 查看帮助信息 -l &#xff5c;--list 查看所有模块 -s 查看模块摘要 Ansible servers -I &#xff5c;-…

天津医科大学临床医学院专升本公共事业管理专业卫生事业管理考纲

天津医科大学临床医学院高职升本科专业课考试大纲公共事业管理专业《卫生事业管理学》考试大纲 一、考试基本要求 本考试大纲为公共事业管理专业高职升本科入学考试内容&#xff0c;主要考察学生对卫生事业管理学的基本概念、基本理论以及解决问题的基本方法的掌握程度&#…

SpringBoot 2 集成Spark 3

前提条件: 运行环境&#xff1a;Hadoop 3.* Spark 3.* ,如果还未安装相关环境&#xff0c;请参考&#xff1a; Spark 初始 CentOS 7 安装Hadoop 3 单机版 SpringBoot 2 集成Spark 3 pom.xml <?xml version"1.0" encoding"UTF-8"?> <pro…

2024年深度学习、计算机视觉与大模型面试题综述,六大专题数百道题目

DeepLearning-Interview-Awesome-2024 本项目涵盖了大模型(LLMs)专题、计算机视觉与感知算法专题、深度学习基础与框架专题、自动驾驶、智慧医疗等行业垂域专题、手撕项目代码专题、优异开源资源推荐专题共计6大专题模块。我们将持续整理汇总最新的面试题并详细解析这些题目&a…

9. UVM Test

test位于启动环境组件构建的层次顶部(top of the hierarchical)。它还负责测试平台配置和激励生成过程。根据验证计划中提到的设计特征和功能&#xff0c;编写测试。用户定义的测试类源自uvm_test。 9.1 uvm_test class hierarchy 类声明&#xff1a; virtual class uvm_test …

Sublime Text 4 中文汉化教程(Version: Build 4169)

Sublime Text 4汉化 1 知识小课堂1.1 sublim简介1.2 其他编辑器 2 安装过程2.1 安装Install Package Control2.2 Install Package2.3 安装工具包2.4 常用的插件2.5 安装中文包 1 知识小课堂 1.1 sublim简介 Sublime是一款代码编辑器&#xff0c;致力于为开发人员提供快速、高…

玩客云 青龙面板

一、刷机 需要的工具&#xff0c;镊子&#xff0c;双公头USB&#xff08;可以自己做&#xff09;&#xff0c;U盘 青龙面板全教程 | Anubis的小窝 powersee教程 玩客云导航固件使用说明 安装教程 玩客云乱七八糟的坑 静态IP配置 玩客云第二版固件说明 docker 下载器 …

【MySQL】数据库中为什么使用B+树不用B树

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; 数 据 库 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 B树的特点和应用场景&#xff1a; B树相对于B树的优势&#xff1a; 结论&#xff1a; 结语 我的其他博客 前言 在数据…

GPT-5、开源、更强的ChatGPT!OpenAI公布2024年计划

年终岁尾&#xff0c;正值圣诞节热闹气氛的OpenAI写下了2024年的发展清单。 OpenAI联合创始人兼首席执行官Sam Altman在社交平台公布&#xff0c;AGI&#xff08;稍晚一些&#xff09;、GPT-5、更好的语音模型、更高的费率限制&#xff1b; 更好的GPTs&#xff1b;更好的推理…

CSS 文字弹跳效果

鼠标移过去 会加快速度 <template><div class"bounce"><p class"text" :style"{animationDuration: animationDuration}">欢迎使用UniApp Vue3&#xff01;</p></div> </template><script> export d…