鸿蒙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一次, 赋值? 搞不懂这是什么原理, 有懂的大佬可以留言

相关推荐
SuperHeroWu74 小时前
【HarmonyOS】Beta最新对外版本IDE下载和环境配置
ide·华为·harmonyos
xq9527--6 小时前
鸿蒙next web组件和h5 交互实战来了
华为·harmonyos
PlumCarefree15 小时前
基于鸿蒙API10的RTSP播放器(八:音量和亮度调节功能的整合)
华为·ffmpeg·音视频·harmonyos
Android技术栈17 小时前
鸿蒙开发(NEXT/API 12)【使用fetchsync发送同步网络请求 (C/C++)】 远场通信服务
c语言·网络·c++·信息与通信·harmonyos·鸿蒙系统·openharmony
OH五星上将1 天前
OpenHarmony(鸿蒙南向开发)——标准系统移植指南(一)
harmonyos·移植·openharmony·鸿蒙开发·鸿蒙内核·子系统
OH五星上将1 天前
OpenHarmony(鸿蒙南向开发)——标准系统移植指南(二)Linux内核
linux·驱动开发·嵌入式硬件·移动开发·harmonyos·鸿蒙开发·鸿蒙内核
JohnLiu_2 天前
HarmonyOS Next鸿蒙扫一扫功能实现
华为·harmonyos·鸿蒙·扫一扫
weixin_424343022 天前
2024年8月HarmonyOS鸿蒙应用开发者高级认证全新题库
华为·harmonyos
让开,我要吃人了2 天前
OpenHarmony鸿蒙( Beta5.0)RTSPServer实现播放视频详解
驱动开发·嵌入式硬件·华为·移动开发·harmonyos·鸿蒙·openharmony
OH五星上将2 天前
OpenHarmony(鸿蒙南向开发)——轻量和小型系统三方库移植指南(二)
驱动开发·移动开发·harmonyos·内存管理·openharmony·鸿蒙内核·鸿蒙移植