HarmonyOS 鸿蒙Next 怎么处理List自定义子组件UI不跟随数据刷新的问题
【问题现象】
获取数据后,在List组件中使用ListItemGroup对数据进行分组展示,ListItem中是自定义的组件,自定义组件里声明变量添加了@ObjectLink,数据的自定义class也添加了@Observed。如图所示,点击删除后,通过日志观察到数据已经删除了,但是UI并没有刷新。
【背景知识】
- List组件支持分组列表。
- @Observed装饰器和@ObjectLink装饰器。
【定位思路】
经过分析,原因是第二个ForEach中的item.enterprise未被状态装饰器修饰,无法观察值的变化。
问题代码如下:
@Builder
listlayout() {
List({ space:12,initialIndex:0 }) {
ForEach(this.enterpriseInfosList, (item: TempEnterpriseInfos,index: number) => {
ListItemGroup({ header:this.itemHead(item.state) }) {
// item.enterprise未被状态装饰器修饰,无法观察值的变化
ForEach(item.enterprise, (item: TempEnterprise,itemIndex: number) => {
ListItem() {
listItemLayout({
item: item,
pageState:this.pageState,
enterpriseid:this.enterpriseid,
selectClick:this.selectClick,
deleteClick:this.deleteClick
})
}.swipeAction({
end: {
// index为该ListItem在List中的索引值。
builder: () => {
this.itemEnd(index, itemIndex)
},
actionAreaDistance:56,
}
})
}, (item: TempEnterprise) =>JSON.stringify(item))
}
}, (item: TempEnterpriseInfos) =>JSON.stringify(item))
}
.width('100%')
.layoutWeight(1)
.multiSelectable(true)
.backgroundColor($r('app.color._f5f5f5'))
.padding({ left:12,right:12 })
}
[@Observed](/user/Observed)
exportclass TempEnterpriseInfos {
state: string =''; // 状态
enterprise: TempEnterpriseArray = [];
constructor(state: string,enterprise: TempEnterpriseArray) {
this.state= state;
this.enterprise= enterprise;
}
}
[@Observed](/user/Observed)
exportclass TempEnterpriseInfosArray extendsArray<TempEnterpriseInfos> {}
[@Observed](/user/Observed)
exportclass TempEnterprise {
enterpriseid: string ='' // 企业id
enterpriseName: string ='' // 企业名称
private_checked: boolean =false; // 选中状态
}
[@Observed](/user/Observed)
export class TempEnterpriseArray extends Array<TempEnterprise> {}
【解决方案】
基于以上分析,需要再定义一个分组的自定义子组件,用@ObjectLink装饰器装饰数据源。
1. 父组件EnterpriseSwitchingPage
代码示例如下:
@Builder
listlayout() {
List({ space: 12, initialIndex: 0 }) {
ForEach(this.enterpriseInfosList, (item: TempEnterpriseInfos, index: number) => {
MyListItemGroup({
index: index,
state: item.state,
enterprise: item.enterprise,
pageState: this.pageState,
enterpriseid: this.enterpriseid,
selectClick: this.selectClick,
deleteClick: this.deleteClick,
enterpriseInfosList: this.enterpriseInfosList
})
}, (item: TempEnterpriseInfos) => JSON.stringify(item))
}
}
2. 子组件MyListItemGroup
代码示例如下:
@Component
struct MyListItemGroup {
@Link pageState: number
@Link enterpriseid: string
@Link selectClick: boolean
@Link deleteClick: boolean
@Prop state: string
@Prop index: number
@State enterprise: TempEnterprise[] = []
[@ObjectLink](/user/ObjectLink) enterpriseInfosList: TempEnterpriseInfosArray
build() {
ListItemGroup({ header:this.itemHead(this.state) }) {
ForEach(this.enterprise, (item: TempEnterprise,itemIndex: number) => {
ListItem() {
listItemLayout({
item: item,
pageState:this.pageState,
enterpriseid:this.enterpriseid,
selectClick:this.selectClick,
deleteClick:this.deleteClick
})
}.swipeAction({
end: {
// index为该ListItem在List中的索引值。
builder: () => {
this.itemEnd(this.index, itemIndex)
},
actionAreaDistance:56,
}
})
}, (item: TempEnterprise) =>JSON.stringify(item))
}
}
}
效果如下:
1 回复
针对HarmonyOS 鸿蒙Next中List自定义子组件UI不跟随数据刷新的问题,通常是因为数据变化没有被状态管理系统正确捕捉,或者子组件没有正确订阅这些变化。以下是一些可能的解决方案:
- 确保数据被状态装饰器修饰:在HarmonyOS中,使用@State、@Observed等状态装饰器来标记需要响应变化的数据。确保所有在UI中使用的数据都被这些装饰器修饰,以便系统能够追踪其变化。
- 避免直接修改数组或对象属性:直接修改数组或对象中的属性可能不会触发UI更新。可以通过创建一个新的数组或对象,并将其赋值给原变量来触发更新。
- 检查子组件的数据绑定:确保子组件正确订阅了父组件传递的数据。如果使用的是LazyForEach等组件,检查其items属性是否绑定到了可观察的数据源上。
- 使用@Link代替@Prop:在某些情况下,使用@Link代替@Prop可以确保子组件能够实时响应父组件的数据变化。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。