在鸿蒙中使用 Repeat 渲染嵌套列表,修改内层列表的一个元素,页面不会更新

问题:在鸿蒙中使用 Repeat 渲染嵌套列表,修改内层列表的一个元素,页面不会更新

数据结构如下:

yaml 复制代码
  interface IListData {
    id: number,
    name: string,
  }

  listData: [
    {
      id: 1,
      name: 'A',
      list: [
        {
          id: 1,
          name: '张三'
        },
        {
          id: 2,
          name: '李四'
        }
      ]
    }
  ]

渲染代码如下:

scss 复制代码
  List({ space: 20 }) {
    Repeat(this.listData).each((ri: RepeatItem<IReportListResponse_list>) => {
      ListItem() {
        Column() {
          Text(this.handleNursingTime(ri.item.name))
            .fontColor('#333333')
            .fontSize('16fp')
            .margin({ bottom: 10 })
          Column() {
            Repeat(ri.item.nursingModelInfoList).each((riChild: RepeatItem<INursingModelInfo>) => {
              Row() {
                Text(this.handleNursingTime(riChild.item.name))
            }).key((item: INursingModelInfo, index) => `${item.id}`)
          }
          .backgroundColor(Color.White)
          .borderRadius(12)
        }
        .alignItems(HorizontalAlign.Start)
      }
    }).key((item: IReportListResponse_list, index) => `${item.id}`)

调用方法删除内层列表的一个元素:

typescript 复制代码
  deleteByReportIndex(id: number) {
    const arr = this.listData.map((item) => {
      item.list = item.list.filter((childItem) => {
        return childItem.id !== id;
      })
      return item;
    })

    this.listData = arr.filter((item) => {
      return item.list.length > 0;
    })
  }

此时内层的元素已被删除了一个,但是页面不会更新

如何解决这个问题?

在 HarmonyOS Next 的状态管理 V2 (@ObservedV2 + @Trace) 中,最核心的规则是:只有真正的类实例(Class Instance)才能被观测,普通的 JSON 对象即便赋值给被装饰的变量,也无法触发深度监听。

直接将接口返回的 JSON 对象赋值给了 this.listData,没有实例化 IListData 类。导致 @Trace 装饰器完全失效,ArkUI 把它当做普通对象处理,所以修改内层数据无法驱动 UI 刷新。

解决方案

  1. 为了让内层列表渲染更稳定,建议给内层的数据也定义一个 @ObservedV2 的类。
ini 复制代码
  interface IList {
    id: number;
    name: string;
  }

  @ObservedV2
  class IListData {
    id: number;
    name: string;
    @Trace list: IList[];
    constructor(id: number, name: string, list: IList[]) {
      this.id = id;
      this.name = name;
      this.list = IList;
    }
  }
  1. 在接口请求回来后,必须用 new 关键字转换数据。
kotlin 复制代码
export struct HistoryList {
  @Local listData: IListData[] = [];

  async fetchData(): Promise<void> {
    const res: AxiosResponse<IBaseResponse<ReportListResponse>> = await getReportList(1, this.pageSize);
    if (res.data.success) {
      this.data = res.data.data;
      this.listData = res.data.data.list.map((item: IReportListResponse_list) => {
        // 这里必须 new 你的类
        return new IListData(item.id, item.name, item.list);
      });
    }
  }

  build(){

  }
}
  1. 这样,当你修改 listData 中的任何一个元素时,UI 都会自动更新。
相关推荐
张元清2 分钟前
React useResizeObserver Hook:追踪元素尺寸变化(2026)
javascript·react.js
赵庆明老师30 分钟前
Vben精讲:16-熟悉Vite前端工具链
前端
瑞瑞小同学3 小时前
处理echarts x轴内容过多,重叠问题
前端·javascript·echarts
HexCIer3 小时前
面向未来的原子化 CSS:UnoCSS 核心架构分析与 Tailwind CSS 现状
前端·css·vite
程序员黑豆3 小时前
鸿蒙应用开发中的单位详解:px、vp、fp、lpx
前端·harmonyos
像我这样帅的人丶你还4 小时前
MCP + npm:给五年前的老系统接上AI
前端·javascript·agent
南一Nanyi4 小时前
依赖注入和控制反转
前端·设计模式·nestjs
小村儿4 小时前
连载14-实战篇--一个半月,我一个人和 Claude Code 搭出一套数字人工程
前端·后端·ai编程
愚公移码4 小时前
蓝凌EKP18产品:流程虚拟机(PVM)
java·开发语言·前端
promiseThen4 小时前
5 分钟上手 Markdown:标题到表格、代码块与简历实战
前端