在鸿蒙中使用 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 都会自动更新。
相关推荐
ywf121516 小时前
前端的dist包放到后端springboot项目下一起打包
前端·spring boot·后端
恋猫de小郭16 小时前
2026,Android Compose 终于支持 Hot Reload 了,但是收费
android·前端·flutter
hpoenixf1 天前
2026 年前端面试问什么
前端·面试
还是大剑师兰特1 天前
Vue3 中的 defineExpose 完全指南
前端·javascript·vue.js
泯泷1 天前
阶段一:从 0 看懂 JSVMP 架构,先在脑子里搭出一台最小 JSVM
前端·javascript·架构
mengchanmian1 天前
前端node常用配置
前端
华洛1 天前
利好打工人,openclaw不是企业提效工具,而是个人助理
前端·javascript·产品经理
xkxnq1 天前
第六阶段:Vue生态高级整合与优化(第93天)Element Plus进阶:自定义主题(变量覆盖)+ 全局配置与组件按需加载优化
前端·javascript·vue.js
A黄俊辉A1 天前
vue css中 :global的使用
前端·javascript·vue.js
小码哥_常1 天前
被EdgeToEdge适配折磨疯了,谁懂!
前端