HarmonyOS 数据传递问题

有一个自定义类型的数组,需要刷新页面,数组定义在MainView里面,传给了SubView,subView用来展示数据,但是实际没有刷新成功,只有初始的时候成功了,参考了说明文档里的Prop装饰器,代码如下:

@Observed 
class Data{ 
 id:string = '' 
 name:string = '' 
} 
@Entry 
@Component 
struct MainView{ 
 @State list1:Data[] = [] 
 @State list2:Data[] = [] 
 @State list3:Data[] = [] 
 recode:number = 1 
 handler?:number 
 aboutToAppear(): void { 
  this.handler = setInterval(()=>{ 
   if(this.list1.length == 0){ 
    for(let i = 0; i < 4; i++){ 
     let data1 = new Data() 
     data1.id = i+'' 
     data1.name = `name${i}` 
     this.list1.push(data1) 
     let data2 = new Data() 
     data2.id = i+'' 
     data2.name = `name${i}` 
     this.list2.push(data2) 
     let data3 = new Data() 
     data3.id = i+'' 
     data3.name = `name${i}` 
     this.list3.push(data3) 
    } 
   } else { 
    //用下面注释的可以更新,但是我希望只改属性值,实际对象属性很多 
    this.list1[0].name = `new name ${this.recode}` 
    // let data = new Data() 
    // data.id = this.list1[0].id 
    // data.name = `new name ${this.recode}` 
    // this.list1[0] = data 
    this.recode++ 
   } 
  }, 1000) 
 } 
 aboutToDisappear(): void { 
  clearInterval(this.handler) 
 } 
 build() { 
  Column(){ 
   SubView({mList:this.list1, name:'第一个'}).width('100%').margin({top:20}) 
   SubView({mList:this.list2, name:'第二个'}).width('100%').margin({top:20}) 
   SubView({mList:this.list2, name:'第三个'}).width('100%').margin({top:20}) 
  }.width('100%') 
 } 
} 
 
@Component 
struct SubView{ 
 @Prop mList:Data[] 
 @Prop name:string 
 build() { 
  Column(){ 
   Text(this.name).fontSize(25) 
   GridRow({columns:2, gutter:{x:10,y:10}}){ 
    ForEach(this.mList,(item:Data,index:number)=>{ 
     GridCol(){ 
      Row(){ 
       Text(item.id).fontColor(Color.Red) 
       Text(item.name).fontColor(Color.Green) 
      }.width('100%').justifyContent(FlexAlign.SpaceEvenly) 
     } 
    }) 
   }.margin({top:10}) 
   .width('100%') 
  }.width('100%') 
 } 
}
HarmonyOS
2024-08-29 15:43:04
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
superinsect

因为Observed修饰的是Data对象而非对象数组,因此向子组件传递对象数组时无法观察数组内的Data变化并刷新UI,当前有两个解决方案:

第一种:在父组件中实现UI的forEach逻辑,子组件仅传递需要观察变化的变量。

@Observed 
class Data { 
  id: string = '' 
  name: string = '' 
} 
 
class Tmp { 
  list: Data[] = [] 
  name: string = '' 
} 
@Entry 
@Component 
struct MainView { 
  @State list1: Data[] = [] 
  recode: number = 1 
  handler?: number 
  aboutToAppear(): void { 
    this.handler = setInterval(() => { 
      if (this.list1.length == 0) { 
        for (let i = 0; i < 4; i++) { 
          let data1 = new Data() 
          data1.id = i + '' 
          data1.name = name${i} 
          this.list1.push(data1) 
        } 
      } else { 
        this.list1[0].name = new name ${this.recode} 
      } 
    }, 1000) 
  } 
  aboutToDisappear(): void { 
    clearInterval(this.handler) 
  } 
  build() { 
    Column() { 
      this.Helper({ name: '第一个', list: this.list1 }) 
}.width('100%') 
 
  } 
  @Builder 
  Helper($$: Tmp) { 
    Column() { 
      Text($$.name).fontSize(25) 
      GridRow({ columns: 2, gutter: { x: 10, y: 10 } }) { 
        ForEach($$.list, (item: Data, index: number) => { 
          GridCol() { 
            SubView2({ item: item }) 
          } 
        }) 
      }.margin({ top: 10 }) 
      .width('100%') 
    } 
  } 
} 
@Component 
struct SubView2 { 
  @ObjectLink item: Data 
  build() { 
    Row() { 
      Text(this.item.id).fontColor(Color.Red) 
      Text(this.item.name).fontColor(Color.Green) 
    }.width('100%').justifyContent(FlexAlign.SpaceEvenly) 
  } 
}

第二种:使用API12提供的@ObservedV2和@Track装饰器(样机rom,ide和sdk需升级至beta1)

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-new-observedv2-and-trace-V5

@ObservedV2 
class Data2 { 
  id: string = '' 
  @Trace name: string = '' 
} 
 
@ObservedV2 
class DataList2 { 
  id:string = '' 
  @Trace list:Data2[] = [] 
} 
@Entry 
@Component 
struct MainView2 { 
  list1: DataList2 = new DataList2() 
  recode: number = 1 
  handler?: number 
  aboutToAppear(): void { 
    this.handler = setInterval(() => { 
      if (this.list1.list.length == 0) { 
        for (let i = 0; i < 4; i++) { 
          let data1 = new Data2() 
          data1.id = i + '' 
          data1.name = name${i} 
          this.list1.list.push(data1) 
        } 
      } else { 
        this.list1.list[0].name = new name ${this.recode} 
      } 
    }, 1000) 
  } 
  aboutToDisappear(): void { 
    clearInterval(this.handler) 
  } 
  build() { 
    Column() { 
      SubView22({ mList: this.list1, name: '第一个' }).width('100%').margin({ top: 20 }) 
    }.width('100%') 
  } 
} 
@Component 
struct SubView22 { 
  mList: DataList2 = new DataList2() 
  name: string = '' 
  build() { 
    Column() { 
      Text(this.name).fontSize(25) 
      GridRow({ columns: 2, gutter: { x: 10, y: 10 } }) { 
        ForEach(this.mList.list, (item: Data2, index: number) => { 
          GridCol() { 
            Row() { 
              Text(item.id).fontColor(Color.Red) 
              Text(item.name).fontColor(Color.Green) 
            }.width('100%').justifyContent(FlexAlign.SpaceEvenly) 
          } 
        }) 
      }.margin({ top: 10 }) 
      .width('100%') 
    }.width('100%') 
  } 
}
分享
微博
QQ
微信
回复
2024-08-29 18:27:24
相关问题
HarmonyOS 关于Provide数据传递问题咨询
409浏览 • 1回复 待解决
HarmonyOS router.getParams()数据传递
494浏览 • 1回复 待解决
HarmonyOS taskpool数据传问题
481浏览 • 1回复 待解决
多hap调用及数据传递,有人知道吗?
1030浏览 • 1回复 待解决
HarmonyOS 视频流数据传
447浏览 • 1回复 待解决
HarmonyOS 传递问题 $$
43浏览 • 1回复 待解决
手机如何与电脑端进行数据传
3333浏览 • 1回复 待解决
router传递hashmap参数问题
1571浏览 • 1回复 待解决
页面关闭时如何传递数据
1971浏览 • 1回复 待解决
this传递问题,该如何解决?
2195浏览 • 1回复 待解决
HarmonyOS oh_package.json5依赖传递问题
744浏览 • 1回复 待解决