HarmonyOS 鸿蒙Next @State标注的二维数组元素变更后选中状态UI未更新

发布于 1周前 作者 bupafengyu 来自 鸿蒙OS

HarmonyOS 鸿蒙Next @State标注的二维数组元素变更后选中状态UI未更新

如标题,存在当前数组 @State saleAttrVOList: Array<Array<GoodsSpecAttrBean>> = [],

元素中存在选中或未选中,通过用户点击更新相关字段,ui未更新 更新代码如下:

updateSku(ruleBid:string) { let list = this.saleAttrVOList for (let index = 0; index < list.length; index++) { const elements = list[index]; for (let index = 0; index < elements.length; index++) { const element = elements[index]; element.isSelected = element.ruleBid === ruleBid if(element.isSelected === true) { this.ruleName = element.ruleValue??’’ } } } this.saleAttrVOList = list  let goodsAttrBean = this.goodsAttributeVOList.find((attrBean:GoodsAttrBean) => { return attrBean.ruleBidList === ruleBid }) if(goodsAttrBean) { this.salePrice = goodsAttrBean.salePrice??‘0’ }  }

2 回复

可以尝试使用[@ObjectLink](/user/ObjectLink)和[@Observed](/user/Observed)类装饰器,[@Observed](/user/Observed)修饰class,然后再通过[@State](/user/State)修饰数组

具体可参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-observed-and-objectlink-V13#概述

[@ObjectLink](/user/ObjectLink)和[@Observed](/user/Observed)要一起使用的, 二维数组嵌套层数太多,需要通过 [@ObjectLink](/user/ObjectLink) 分成一层一层组件进行监听,看您这边代码是写到一个组件中,所以是监听不到的。

具体可参考该链接中的二维数组写法:

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-observed-and-objectlink-V13#%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84

可参考如下:

[@Observed](/user/Observed)
class GoodsSpecAtteBean {
 public textInfo: string
 public isSelect: boolean

 constructor(textInfo: string, isSelect: boolean) {

   this.textInfo = textInfo

   this.isSelect = isSelect

 }
}

[@Observed](/user/Observed)
class GoodsSpecAtteBeanArrays extends Array<GoodsSpecAtteBean> {
 constructor(args: GoodsSpecAtteBean) {

   super(args)

 }
}

[@Component](/user/Component)
struct ItemPage {
 [@ObjectLink](/user/ObjectLink) itemArr: GoodsSpecAtteBeanArrays;

 build() {

   Column() {

     Grid() {

       ForEach(this.itemArr, (item: GoodsSpecAtteBean, index: number) => {

         GridItem() {

           TextContent({ item: item })

         }

       })

     }

   }

   .height(100)

 }
}

[@Component](/user/Component)
struct TextContent {
 [@ObjectLink](/user/ObjectLink) item: GoodsSpecAtteBean

 build() {

   Column() {

     Text(this.item.textInfo)

       .textAlign(TextAlign.Center)

       .padding(8)

       .borderRadius(8)

       .fontColor(this.item.isSelect ? Color.Red : Color.Blue)

       .backgroundColor(this.item.isSelect ? Color.Blue : Color.White)

   }

 }
}

[@Entry](/user/Entry)
[@Component](/user/Component)
struct IndexPage {
 [@State](/user/State) arr: GoodsSpecAtteBeanArrays[] =

   [

     new GoodsSpecAtteBeanArrays(new GoodsSpecAtteBean("hello1", true)),

     new GoodsSpecAtteBeanArrays(new GoodsSpecAtteBean("hello2", false)),

     new GoodsSpecAtteBeanArrays(new GoodsSpecAtteBean("hello3", false))

   ];

 build() {

   Column() {

     ForEach(this.arr, (itemArr: GoodsSpecAtteBeanArrays, index: number) => {

       ItemPage({ itemArr: itemArr })

         .onClick(() => {

           for (let i = 0; i < this.arr.length; i++) {

             if (index === i) {

               this.arr[i][0].isSelect = true

             } else {

               this.arr[i][0].isSelect = false

             }

           }

         })

     })

   }

   .width('100%')

   .height('100%')

   .backgroundColor($r('sys.color.ohos_id_color_sub_background'))

 }
}

在HarmonyOS 鸿蒙Next中,使用@State标注的二维数组元素变更后,选中状态的UI未更新问题,通常是由于@State装饰器仅监听数组的地址值变化,而不直接监听数组中对象属性的变化。当数组中的对象属性发生变化时,虽然数据已经更新,但UI不会自动刷新。

针对这一问题,可以采取以下方法解决:

  1. 复制并更新数组:创建一个临时数组,修改临时数组中的对象属性,然后将临时数组重新赋值给原数组。由于数组地址值发生了变化,UI会重新渲染。
  2. 使用map方法:直接修改数组中的对象属性后,使用map方法遍历数组并返回一个新数组。虽然数组内容可能未变,但由于返回的是一个新数组,其地址值已改变,可以触发UI的重新渲染。

这些方法通过改变数组的地址值或返回新数组来触发页面的重新渲染,从而解决数组元素变化时UI不刷新的问题。

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

回到顶部