HarmonyOS鸿蒙Next中组件内的对象数组如何观察到变化?
HarmonyOS鸿蒙Next中组件内的对象数组如何观察到变化? 代码如下,都是在同一个页面内:
// TestPage.ets
[@Observed](/user/Observed)
class WeekInfo{
text?: string;
value?: number;
selected?: boolean;
}
@State dateInfo:WeekInfo[] = [
{ text: '一', value: 1, selected: false },
{ text: '二', value: 2, selected: false },
{ text: '三', value: 3, selected: false },
{ text: '四', value: 4, selected: false },
{ text: '五', value: 5, selected: false },
{ text: '六', value: 6, selected: false },
{ text: '日', value: 7, selected: false }
]
//TestPage.ets
ForEach(this.dateInfo, (item:WeekInfo) => {
Button(item.text)
// 根据selected改变颜色
.backgroundColor(item.selected?this.buttonCheckedColor:this.buttonUnCheckedColor)
.onClick(() => {
item.selected = !item.selected
console.log(`${item.text}`)
if (item.selected) {
console.log('true')
}else {
console.log('false')
}
})
},(item:WeekInfo) => item.text)
我要在当前的component中检测selected的变化,如何观察?使用@Observed装饰器和@ObjectLink装饰器只能在组件和组件之间传递数据使用吗?同一个组件内如何观察到?
当前代码是可以间断打印true和false,但是无法改变 backgroundColor 的颜色,这个如何解决呢??
更多关于HarmonyOS鸿蒙Next中组件内的对象数组如何观察到变化?的实战教程也可以访问 https://www.itying.com/category-93-b0.html
【解决方案】
监听数组内对象属性变化可以通过@Observed配合@ObjectLink装饰符实现。@Observed用于类,标记类为可观察对象,系统自动生成代理类监听类内部嵌套对象属性的变化。@ObjectLink用于变量建立与[@Observed](/user/Observed)类实例的双向绑定,监听对象内部属性变化并触发UI更新。以下是详细实现逻辑代码:
[@Observed](/user/Observed)
class WeekInfo{
text?: string;
value?: number;
selected?: boolean;
constructor(text:string,value:number,selected:boolean) {
this.text = text
this.value = value
this.selected = selected
}
}
@Component
struct DateInfo{
[@ObjectLink](/user/ObjectLink) dateInfo:WeekInfo
buttonCheckedColor: ResourceColor = Color.Blue;
buttonUnCheckedColor: ResourceColor = Color.Red;
build(){
Button(this.dateInfo.text)
// 根据selected改变颜色
.backgroundColor(this.dateInfo.selected?this.buttonCheckedColor:this.buttonUnCheckedColor)
.onClick(() => {
this.dateInfo.selected = !this.dateInfo.selected
console.log(`${this.dateInfo.text}`)
if (this.dateInfo.selected) {
console.log('true')
}else {
console.log('false')
}
})
}
}
@Entry
@Component
struct PageTest {
@State dateInfos:WeekInfo[] = [
new WeekInfo( '一', 1, false ),
new WeekInfo( '二', 2, false ),
new WeekInfo( '三', 3, false ),
new WeekInfo( '四', 4, false ),
new WeekInfo( '五', 5, false ),
new WeekInfo( '六', 6, false ),
new WeekInfo( '日', 7, false )
]
build() {
Column(){
//TestPage.ets
ForEach(this.dateInfos, (item:WeekInfo) => {
DateInfo({dateInfo:item})
},(item:WeekInfo) => item.text)
}
}
}
更多关于HarmonyOS鸿蒙Next中组件内的对象数组如何观察到变化?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
好的谢谢,
可以使用ObeservedV2和@Trace来实现,参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-observedv2-and-trace#trace装饰对象数组
注意:使用@ObservedV2与@Trace装饰器的类,需通过new操作符实例化后,才具备被观测变化的能力。
在HarmonyOS Next中,当直接修改对象数组元素属性时,UI不会自动刷新。这是因为@State装饰的数组只监听数组本身的引用变化,而不监听数组内部对象属性的变化。
解决方案:
- 使用数组重新赋值:
.onClick(() => {
// 创建新数组,修改对应元素的selected属性
this.dateInfo = this.dateInfo.map((week, index) =>
index === itemIndex ? {...week, selected: !week.selected} : week
);
})
- 或者使用@Observed + @ObjectLink组合(虽然你提到在同一个组件内):
[@Observed](/user/Observed)
class WeekInfo {
// ...
}
@Component
struct WeekButton {
[@ObjectLink](/user/ObjectLink) item: WeekInfo
build() {
Button(this.item.text)
.backgroundColor(this.item.selected ? buttonCheckedColor : buttonUnCheckedColor)
.onClick(() => {
this.item.selected = !this.item.selected
})
}
}
// 在父组件中使用
ForEach(this.dateInfo, (item: WeekInfo) => {
WeekButton({ item: item })
}, (item: WeekInfo) => item.text)
推荐使用第一种方法,通过创建新数组来触发状态更新,这是最直接有效的解决方案。

