【HarmonyOS NEXT】点击按钮无法触发子组件渲染

 【关键字】

子组件 / 子视图 / @Observed / @ObjectLink / 渲染

【问题描述】

参考@Observed装饰器和@ObjectLink装饰器,但抽取了一个ClassB的中间类编写了一个demo页面,示例代码如下:

let NextID: number = 1;

@Component
struct ViewA {
  // 子组件ViewA的@ObjectLink的类型是ClassA
  @ObjectLink a: ClassA;
  label: string = 'ViewA1';

  build() {
    Row() {
      Button(`ViewA [${this.label}] this.a.c = ${this.a.c} +1`)
        .onClick(() => {
          this.a.c += 1;
        })
    }
  }
}

@Entry
@Component
struct Index {
  // ViewB中有@State装饰的ClassA[]
  @State arrA: ClassB = new ClassB()

  build() {
    Column() {
      ForEach(this.arrA.arrA,
        (item: ClassA) => {
          Row() {
            Button(`ViewA [${item.c}] this.a.c = ${item.c} +1`)
              .onClick(() => {
                item.c += 1;
              })
          }
          // ViewA({ label: `#${item.id}`, a: item })
        },
        (item: ClassA) => item.id.toString()
      )
      Button(`ViewB: chg item property in middle`)
        .onClick(() => {
          // this.arrA.arrA[Math.floor(this.arrA.arrA.length / 2)].c = 10;
          this.arrA.change();
        })
    }
  }
}

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

  constructor(c: number) {
    this.id = NextID++;
    this.c = c;
  }
}

@Observed
class ClassB {
  arrA: ClassA[] = [new ClassA(0), new ClassA(0)];

  change() {
    this.arrA[Math.floor(this.arrA.length / 2)].c += 10;
  }
}

在此demo中,点击按钮无法触发子组件渲染,语法校验会报如下错误:Assigning the attribute 'item' to the '@ObjectLink' decorated attribute 'a' is not allowed. <ArkTSCheck>

【解决方案】

可参考如下代码实现,需要注意的是要将DevEco Studio和SDK升级到近期的TOD版本

let NextID: number = 1;

@Component
struct ViewA {
// 子组件ViewA的@ObjectLink的类型是ClassA
@ObjectLink a: ClassA;
label: string = 'ViewA1';

build() {
Row() {
Button("子组件"+`ViewA [${this.label}] this.a.c = ${this.a.c} +1`)
.onClick(() => {
this.a.c += 1;
})
}
}
}

@Entry
@Component
struct Index {
// ViewB中有@State装饰的ClassA[]
@State arrA: ClassB = new ClassB()

build() {
Column() {
ForEach(this.arrA.arrA,
(item: ClassA) => {
// Row() {
// Button(`ViewA [${item.c}] this.a.c = ${item.c} +1`)
// .onClick(() => {
// item.c += 1;
// })
// }
ViewA({ label: `#${item.id}`, a: item })
},
(item: ClassA) => item.id.toString()
)
Button("父组件"+`ViewB: chg item property in middle`)
.onClick(() => {
// this.arrA.arrA[Math.floor(this.arrA.arrA.length / 2)].c = 10;
this.arrA.change();
})
}
}
}

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

constructor(c: number) {
this.id = NextID++;
this.c = c;
}
}

@Observed
class ClassB {
arrA: ClassA[] = [new ClassA(0), new ClassA(0)];

change() {
this.arrA[Math.floor(this.arrA.length / 2)].c += 10;
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值