HarmonyOS鸿蒙Next中页面布局中,数据绑定,界面刷新问题

HarmonyOS鸿蒙Next中页面布局中,数据绑定,界面刷新问题 有这一样个数据对象

export default class InfoData { dataBaseInfo : RowInfo[] = []; dataTime : RowInfo[] =[]; }

在页面上这样使用

@State infoData: InfoData = new InfoData (); ForEach(this.infoData.dataBaseInfo, (row: RowInfo) => { Row() { ForEach(row.cellInfo, (cell: CellInfo) => { Text(cell.text) .textAlign(cell.textAlign) .layoutWeight(cell.layoutWeight) .fontWeight(cell.fontWeight) .fontSize(cell.fontSize) .fontColor(cell.fontColor) .padding({ top: 8, bottom: 8 }) .id(“edt_” + row.row + “_” + cell.col) .onClick(() => { if (cell.col == 0) return; this.infoData.dataBaseInfo= Helper.refData(this.infoData.dataBaseInfo, row.row, cell.col); }); } .backgroundColor(row.backgroundColor) .justifyContent(FlexAlign.Start) }); }

点击事件的会调用Helper.refData()刷新dataBaseInfo里面的数据,现在也执行了刷新方法,可界面没有刷新

如果单独定义dataBaseInfo : RowInfo[] = []; 界面上绑定this.dataBaseInfo,则界面会刷新,请问这是什么原因?


更多关于HarmonyOS鸿蒙Next中页面布局中,数据绑定,界面刷新问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

this.infoData.dataBaseInfo= Helper.refData(this.infoData.dataBaseInfo, row.row, cell.col); 这里改成这样 this.infoData = Helper.refData(this.infoData, row.row, cell.col); 解决了,哈哈,昨晚上突然想到,搞不懂原因

更多关于HarmonyOS鸿蒙Next中页面布局中,数据绑定,界面刷新问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


HarmonyOS Next中数据绑定采用ArkTS声明式UI范式,通过@State@Link等装饰器管理状态。页面刷新由框架自动触发,当装饰器标记的变量值变更时,关联的UI组件会自动更新。使用@Observed@ObjectLink可管理嵌套对象。

在HarmonyOS Next中,@State装饰器仅能观察到其直接修饰的属性本身(即infoData这个对象引用)的变化。当你执行this.infoData.dataBaseInfo = Helper.refData(...)时,你实际上是在修改infoData对象内部的一个属性(dataBaseInfo数组),而infoData这个对象引用本身并没有改变。因此,@State装饰器无法感知到这个内部属性的变更,导致UI不会刷新。

解决方案如下:

  1. 为需要深度观察的属性单独使用@State装饰器(正如你测试成功的方法):

    @State dataBaseInfo: RowInfo[] = [];
    // 将dataBaseInfo从InfoData类中分离出来,或作为页面的一个独立状态
    
  2. 使用@Observed@ObjectLink装饰器进行嵌套对象观察

    • InfoData类用@Observed装饰。
    • 在UI组件中使用@ObjectLink来装饰infoData,这样它就能观察InfoData类内部被@Track装饰的属性的变化。
    • 注意:RowInfoCellInfo如果也是类,并且需要观察其内部变化,也需要用@Observed装饰。

    示例代码结构:

    // 1. 用@Observed装饰数据类
    @Observed
    class InfoData {
      @Track dataBaseInfo: RowInfo[] = []; // 需要观察的属性用@Track标记
      @Track dataTime: RowInfo[] = [];
    }
    
    @Observed
    class RowInfo {
      @Track cellInfo: CellInfo[] = [];
      // ... 其他属性
    }
    
    // 2. 在组件中,使用@ObjectLink替代@State
    @Entry
    @Component
    struct MyPage {
      @ObjectLink infoData: InfoData; // 使用@ObjectLink建立双向绑定
    
      build() {
        // ... 你的ForEach循环结构保持不变
        // 当infoData.dataBaseInfo被重新赋值时,@ObjectLink能观察到@Track属性的变化
      }
    }
    

    在你的点击事件中,this.infoData.dataBaseInfo = Helper.refData(...)这行赋值语句,由于dataBaseInfo@Track装饰,且infoData@ObjectLink,所以UI会响应这次更新。

  3. 直接替换整个infoData对象(不推荐,除非必要):

    // 在onClick事件中
    this.infoData = ... // 创建一个全新的InfoData对象并整体赋值
    

    这种方式会触发@State的观察,因为对象引用改变了,但性能开销较大,且如果其他地方持有对旧对象的引用,可能会产生问题。

总结: 你遇到的问题核心是@State的浅观察机制。对于嵌套对象或数组内部属性的修改,推荐使用方案2(@Observed + @ObjectLink + @Track,这是HarmonyOS ArkUI为复杂数据结构设计的标准响应式方案。你单独定义dataBaseInfo能成功,是因为它被@State直接观察,赋值操作直接被捕获。

回到顶部