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

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

【问题现象】

获取数据后,在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))
    }
  }
}

效果如下:

点击放大

点击放大


更多关于HarmonyOS鸿蒙Next中怎么处理List自定义子组件UI不跟随数据刷新的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中怎么处理List自定义子组件UI不跟随数据刷新的问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,处理List自定义子组件UI不跟随数据刷新的问题,可以通过以下步骤解决:

  1. 定义分组的自定义子组件:创建一个新的子组件MyListItemGroup,并在其中使用@ObjectLink装饰器来装饰数据源。

  2. 父组件中使用自定义子组件:在父组件EnterpriseSwitchingPage中,使用MyListItemGroup来替代原有的ListItemGroup,并传递相关参数。

  3. 子组件中处理数据刷新:在MyListItemGroup中,确保@ObjectLink装饰的数据源能够正确触发UI刷新。

具体代码示例如下:

父组件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))
  }
}

子组件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 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: {
            builder: () => {
              this.itemEnd(this.index, itemIndex)
            },
            actionAreaDistance: 56,
          }
        })
      }, (item: TempEnterprise) => JSON.stringify(item))
    }
  }
}

通过以上步骤,可以确保List自定义子组件的UI能够正确跟随数据刷新。

回到顶部