鸿蒙next中使用@Observed和@ObjectLink遇到的坑, 数据更新但UI没更新

1. 还原本次事故

首先定义bean, 并用@Observed修饰

ini 复制代码
@Observed
export class PackAudio {
  audioUrl: string = ""
  createdAt: string = ""
  duration: number = 0
  name: string = ""
  objectId: string = ""
  belong?: string
  sort: number = 0
  isPlaying: boolean = false
  isNew: boolean = false
  }

自定义PackAudioView组件, 并且用@ObjectLink修饰

scss 复制代码
import { PackAudio } from './PackAudio';

@Component
export struct PackAudioView {
  @ObjectLink item: PackAudio;
  @Prop index: number = 0;
  @Prop currentClickIndex: number = -1;
  ownerObjectId: string = '';
  onClickItem?: () => void;

  build() {
    Row() {
      Stack() {
        Text('' + (this.index + 1))
          .width(54)
          .height(65)
          .textAlign(TextAlign.Center)
          .fontSize(15)
      }

      Column() {
        Text(this.item.name).fontSize(15).maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })
        Text(`时长: ${this.item.duration}`)
          .fontSize(12)
          .margin({ top: 4 })
      }.layoutWeight(1).alignItems(HorizontalAlign.Start)

    }.width("100%").height(65).onClick(() => {
      this.onClickItem!()
    }).backgroundColor(this.currentClickIndex === this.index ? Color.Grey : Color.White)
  }
}

让我们在主页使用它

typescript 复制代码
import { ToastUtil } from '@pura/harmony-utils';
import { PackAudio } from './PackAudio';
import { PackAudioView } from './PackAudioView';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  @State audios: Array<PackAudio> = [
    {
      audioUrl: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png',
      createdAt: '2021-01-01',
      duration: 10,
      name: '测试1',
      objectId: '1',
      sort: 1,
      isPlaying: false,
      isNew: false
    },
    {
      audioUrl: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png',
      createdAt: '2021-01-01',
      duration: 10,
      name: '测试2',
      objectId: '1',
      sort: 1,
      isPlaying: false,
      isNew: false
    },
    {
      audioUrl: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png',
      createdAt: '2021-01-01',
      duration: 10,
      name: '测试3',
      objectId: '1',
      sort: 1,
      isPlaying: false,
      isNew: false
    },
  ]
  @State currentClickIndex: number = -1

  build() {
    Column() {
      Text("测试测试")
      List() {
        ForEach(this.audios, (item: PackAudio, index: number) => {
          ListItem() {
            PackAudioView({
              item: item,
              index,
              currentClickIndex: this.currentClickIndex,
              onClickItem: () => {
                item.name = `点击了: ${item.name}`
                this.currentClickIndex = index
                ToastUtil.showToast('点击了: ' + item.name)
              }
            })
          }
        })
      }
    }
    .height('100%')
    .width('100%')
  }
}

最后的结果就是, 虽然我们改变item.name的值, 但是UI确没有更新. 很诡异, 搞了很久, 最后阅读文档才发现必须要求new对象出来!

2. 修改

修改我们赋值的方式, 添加构造函数

ini 复制代码
@Observed
export class PackAudio {
  audioUrl: string = ""
  createdAt: string = ""
  duration: number = 0
  name: string = ""
  objectId: string = ""
  belong?: string
  sort: number = 0
  isPlaying: boolean = false
  isNew: boolean = false

  constructor(audioUrl: string, createdAt: string, duration: number, name: string, objectId: string, belong?: string, sort: number = 0, isPlaying: boolean = false, isNew: boolean = false) {
    this.audioUrl = audioUrl
    this.createdAt = createdAt
    this.duration = duration
    this.name = name
    this.objectId = objectId
    this.belong = belong
    this.sort = sort
    this.isPlaying = isPlaying
    this.isNew = isNew
  }
}

然后我们赋值的时候用new出来

typescript 复制代码
import { ToastUtil } from '@pura/harmony-utils';
import { PackAudio } from './PackAudio';
import { PackAudioView } from './PackAudioView';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  @State audios: Array<PackAudio> = [
    new PackAudio(
      'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png',
      '2021-01-01',
      10,
      '测试1',
      '1',
      "2",
      1,
      false,
      false
    ),
  ]
  @State currentClickIndex: number = -1

  build() {
    Column() {
      Text("测试测试")
      List() {
        ForEach(this.audios, (item: PackAudio, index: number) => {
          ListItem() {
            PackAudioView({
              item: item,
              index,
              currentClickIndex: this.currentClickIndex,
              onClickItem: () => {
                item.name = `点击了: ${item.name}`
                this.currentClickIndex = index
                ToastUtil.showToast('点击了: ' + item.name)
              }
            })
          }
        })
      }
    }
    .height('100%')
    .width('100%')
  }
}

这样就完美解决了...所以当我们从服务器获取到数据的array后, 也不能直接使用? 还需要new一次, 赋值? 搞不懂这是什么原理, 有懂的大佬可以留言

相关推荐
柒儿吖1 天前
Electron for 鸿蒙PC 窗口问题完整解决方案
javascript·electron·harmonyos
xiaocao_10231 天前
鸿蒙手机上有哪些比较好用的记事提醒工具?
华为·智能手机·harmonyos
坚果派·白晓明1 天前
开源鸿蒙终端工具Termony构建HNP包指导手册Mac版
macos·开源·harmonyos
ChinaDragon1 天前
HarmonyOS:属性动画
harmonyos
坚果派·白晓明1 天前
开源鸿蒙终端工具Termony增加外部HNP包合入base.hnp的设计与实现实战教程
华为·开源·harmonyos
HarmonyOS_SDK1 天前
性能优化 | HarmonyOS预加载,三步即可提升APP页面的响应速度
harmonyos
坚果派·白晓明1 天前
开源鸿蒙终端工具Termony环境配置指导手册Mac版
开源·harmonyos·项目实战
啃火龙果的兔子1 天前
Kotlin 修改安装到桌面后的应用图标
开发语言·kotlin·harmonyos
白茶三许1 天前
关于Flutter版本过低导致鸿蒙虚拟机启动失败的问题解决
flutter·开源·harmonyos·openharmony
不爱吃糖的程序媛1 天前
鸿蒙PC Dock 栏隐藏“打开新窗口“功能实现详解
华为·harmonyos