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: StringDatabuild() {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: StringDataV2build() {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能监听到该层的变化)。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全自动洗衣机什么牌子好?最好用的四款内衣洗衣机推荐

随着科技的快速发展&#xff0c;现在的人们越来越注重自己的卫生问题&#xff0c;不仅在吃上面会注重卫生问题&#xff0c;在用的上面也会更加严格要求&#xff0c;而衣服做为我们最贴身的东西&#xff0c;我们对它的要求也会更加高&#xff0c;所以最近这几年较火爆的无疑是内…

游戏行业变天,游戏股遭暴击,腾讯网易等股票还能投资吗?

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 国家新闻出版署发布游戏新规 12月22日国家新闻出版署发布了《网络游戏管理办法》&#xff08;草案征求意见稿&#xff09;&#xff0c;其中提到网络游戏不得设置每日登陆、首次充值、连续充值等诱导性奖励&#xff0c;而且…

Ubuntu系统如何安装SVN服务端并通过客户端无公网ip实现远程访问?

文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改authz文件 3. 启动svn服务4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射本地端口 5. 测试公网访问6. 配置固定公网TCP端口地址6.1 保留一个固定的公网TCP端口地址6…

小狐狸ChatGPT系统 H5前端底部菜单导航文字修改方法

小狐狸ChatGPT系统后端都前端都是编译过的&#xff0c;需要改动点什么非常难处理&#xff0c;开源版修改后也需要编译后才能使用&#xff0c;大部分会员也不会使用&#xff0c;像简单的修改下底部菜单文字、图标什么的可以对照处理。这里以小狐狸ChatGPT系统1.9.2版本H5端为例&…

Vue中Render函数、_ref属性、_props配置的使用

Render函数 由于导入的vue为vue.runtime.xxx.js是运行版的vue.只包含&#xff1a;核心功能&#xff1a;没有模板解析器 完整版的Vue为vue.js包含&#xff1a;核心功能模板解析器 vue.runtime.esm.js中的esm为ES6的模块化 //导入的vue并非完整的vue&#xff0c;这样做的好处是…

Pandas有了平替Polars

Polars是一个Python数据处理库&#xff0c;旨在提供高性能、易用且功能丰富的数据操作和分析工具。它的设计灵感来自于Pandas&#xff0c;但在性能上更加出色。 Polars具有以下主要特点&#xff1a; 强大的数据操作功能&#xff1a;Polars提供了类似于Pandas的数据操作接口&am…

差不多,冬至......

冬/至/快/乐 老广有句话“冬大过年”&#xff0c;冬至作为一年中的最重要时节之一 在古时候人们要完成一大串必做清单&#xff0c;让这一天充满仪式感 而现代人的“过冬”仪式感更多寄托在种种“至味”中 冬至“食”刻,南北独有的仪式感 南VS北 南吃清补 老广腊味“冬日…

微信小程序~如何设置页面的背景色

微信小程序~如何设置页面的背景色 众所周知&#xff0c;微信小程序每个页面由.json&#xff0c;.scss&#xff0c;.ts&#xff0c;.wxml这四个文件组成。 有的小伙伴会发现&#xff0c;需要给页面加背景色的时候&#xff0c;只需在此页面的.scss文件中写个page{background-colo…

基于python的selenium

一.安装 安装WebDriver 查看chrome版本号&#xff0c;设置-帮助-关于Google chrome&#xff0c;找到版本号。 可以到这个网站进行下载对应版本的chromedriver,如果chrome浏览器版本过高,可以下载最新版的chromedriver进行使用 Chrome for Testing availability 下载下来之后…

vscode中使用GitHub Copilot Chat

文章目录 一、什么是Github Copilot Chat二、安装使用三、如何使用1. 聊天功能2. 内联功能 一、什么是Github Copilot Chat GitHub Copilot Chat 由 OpenAI 的 GPT-4 大型多模态模型提供支持&#xff0c;能带来更准确的代码建议、解释和指导。GitHub Copilot Chat 的内联功能可…

axios进行图片上传组件封装

文章目录 前言图片上传接口&#xff08;axios通信)图片上传使用upload上传头像效果展示总结 前言 node项目使用 axios 库进行简单文件上传的模块封装。 图片上传接口&#xff08;axios通信) 新建upload.js文件&#xff0c;定义一个函数&#xff0c;该函数接受一个上传路径和一…

.NET 8最强新功能:键控服务依赖注入

什么是键控服务依赖注入&#xff1f; 在之前的依赖注入中&#xff0c;服务是根据其类型进行注册和解析的。如果出现同一接口有多个实现怎么办呢&#xff1f;这时候就可以使用.NET 8的新功能“键控服务依赖注入”。它允许您注册接口的多个实现&#xff0c;每个实现都与一个唯一…