HarmonyOS @builder方法的ui不刷新

@Entry
@Component
export struct AAMainPage {
  // ViewB中有@State装饰的ClassA[]
  @State arrA: ClassA[] = [new ClassA(0), new ClassA(0)];

  build() {
    Column() {

      hahah({ a: this.arrA[0] })

      ForEach(this.arrA, (item: ClassA, index: number) => {
        hahah({ a: item }).backgroundColor('red')
      }, (item: ClassA, index: number) => index + "")

      this.testBuilder(this.arrA[0])

      Button(`ViewB:  item property in middle`)
        .width(320)
        .margin(10)
        .onClick(() => {
          this.arrA[0].c = 10;
        })
    }
  }

  @Builder
  testBuilder($$: ClassA) {
    Text($$.c + " builder")
  }
  // @Builder
  // testBuilder(a: ClassA) {
  //   Text(a.c + " builder")
  // }
}

@Preview
@Component
export struct hahah {
  @ObjectLink a: ClassA
  build() {
    Text(this.a.c + " 123213")
  }
}
let NextID: number = 1;

@Observed
class ClassA {
  public id: number;
  public c: number;

  constructor(c: number) {
    this.id = NextID++;
    this.c = c;
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
HarmonyOS
2024-12-24 14:50:26
1275浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
aquaa

调用@Builder装饰的函数默认按值传递。当传递的参数为状态变量时,状态变量的改变不会引起@Builder方法内的UI刷新。所以当使用状态变量的时候,推荐使用按引用传递。此时,引用传递的值必须要为@State修饰。

详见:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-builder-V5#参数传递规则

修改建议:

@Entry
@Component
export struct AAMainPage {
  // ViewB中有@State装饰的ClassA[]
  @State arrA: ClassA[] = [new ClassA(2),new ClassA(3)];
  @State changeNum: number = 0


  build() {
    Column() {

      hahah({ a: this.arrA[0] })

      ForEach(this.arrA, (item: ClassA, index: number) => {
        hahah({ a: item }).backgroundColor('red')
      }, (item: ClassA, index: number) => index + JSON.stringify(item))

      testBuilder({c:this.changeNum})
      Button(`ViewB: chg item property in middle`)
        .width(320)
        .margin(10)
        .onClick(() => {
          this.arrA[0].c = 10;
          this.changeNum = this.arrA[0].c
          console.log('cccc-',JSON.stringify(this.arrA))
        })
    }
  }


  // @Builder
  // testBuilder(a: ClassA) {
  // Text(a.c + " builder")
  // }
}

@Builder function testBuilder($$: ClassB) {
  Text($$.c + " builder")
}


@Observed
class ClassA {
  id: number = 0;
  c: number = 0;

  constructor(c: number) {
    this.id = Math.random();
    this.c = c;
  }
}

class ClassB {
  c: number = 0
}

@Component
struct hahah {
  @ObjectLink a: ClassA
  build() {
    Text(this.a.c + " 123213")
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.

目前@Builder设计模式是这样,刷新内容必须用引用传递。示例中的@observed 修饰的实体类采用了构造方法,不能作为引用传递。只要是引用传递就可以,不一定非要$$。按引用传递参数时,如果在@Builder方法内调用自定义组件,ArkUI提供$$作为按引用传递参数的范式。如果在@Builder方法内调用自定义组件或者其他@Builder方法,ArkUI提供$$作为按引用传递参数的范式。

分享
微博
QQ
微信
回复
2024-12-24 17:25:30


相关问题
HarmonyOS @Builder UI刷新问题
752浏览 • 1回复 待解决
HarmonyOS UI刷新
843浏览 • 1回复 待解决
HarmonyOS UI刷新问题
826浏览 • 1回复 待解决
HarmonyOS LIst组件UI刷新
607浏览 • 1回复 待解决
HarmonyOS 更新数据后UI刷新
1071浏览 • 1回复 待解决
IF条件变化后UI刷新
1463浏览 • 1回复 待解决
状态装饰器 ui刷新问题
3146浏览 • 1回复 待解决
HarmonyOS 是否有种主动刷新UI方法
775浏览 • 1回复 待解决
修改ForEach使用数据对象,UI刷新
3041浏览 • 1回复 待解决
HarmonyOS @Builder内容如何刷新
618浏览 • 1回复 待解决
HarmonyOS 懒加载列表更改属性UI刷新
810浏览 • 1回复 待解决
HarmonyOS 主线程刷新UI
1173浏览 • 1回复 待解决
UI预览不会自动刷新, 且刷新较慢
2006浏览 • 1回复 待解决