【关键字】
子组件 / 子视图 / @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;
}
}