在鸿蒙中使用 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 都会自动更新。
相关推荐
柳杉1 小时前
使用Ai从零开发智慧水利态势感知大屏(开源)
前端·javascript·数据可视化
兆子龙2 小时前
从高阶函数到 Hooks:React 如何减轻开发者的心智负担(含 Demo + ahooks 推荐)
前端
狗胜2 小时前
测试文章 - API抓取
前端
三小河2 小时前
VS Code 集成 claude-code 教程:告别海外限制,无缝对接国内大模型
前端·程序员
jerrywus2 小时前
前端老哥的救命稻草:用 Obsidian 搞定 Claude Code 的「金鱼记忆」
前端·agent·claude
球球pick小樱花2 小时前
游戏官网前端工具库:海内外案例解析
前端·javascript·css
用户60572374873082 小时前
AI 编码助手的规范驱动开发 - OpenSpec 初探
前端·后端·程序员
狗胜2 小时前
AI观察日记 2026-03-02|CLAUDE、TYPE、APPFUNCTIONS:掘金热门里的下一步信号
前端