HarmonyOS 鸿蒙Next 怎么处理List自定义子组件UI不跟随数据刷新的问题

发布于 1周前 作者 itying888 最后一次编辑是 5天前 来自 鸿蒙OS

【问题现象】

获取数据后,在List组件中使用ListItemGroup对数据进行分组展示,ListItem中是自定义的组件,自定义组件里声明变量添加了@ObjectLink,数据的自定义class也添加了@Observed。如图所示,点击删除后,通过日志观察到数据已经删除了,但是UI并没有刷新。

点击放大

点击放大

【背景知识】

【定位思路】

经过分析,原因是第二个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不跟随数据刷新的问题,通常是因为数据变化没有被状态管理系统正确捕捉,或者子组件没有正确订阅这些变化。以下是一些可能的解决方案:

  1. 确保数据被状态装饰器修饰:在HarmonyOS中,使用@State@Observed等状态装饰器来标记需要响应变化的数据。确保所有在UI中使用的数据都被这些装饰器修饰,以便系统能够追踪其变化。
  2. 避免直接修改数组或对象属性:直接修改数组或对象中的属性可能不会触发UI更新。可以通过创建一个新的数组或对象,并将其赋值给原变量来触发更新。
  3. 检查子组件的数据绑定:确保子组件正确订阅了父组件传递的数据。如果使用的是LazyForEach等组件,检查其items属性是否绑定到了可观察的数据源上。
  4. 使用@Link代替@Prop:在某些情况下,使用@Link代替@Prop可以确保子组件能够实时响应父组件的数据变化。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部