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

相关推荐
幽蓝计划5 小时前
HarmonyOS NEXT仓颉开发语言实战案例:动态广场
华为·harmonyos
万少11 小时前
第五款 HarmonyOS 上架作品 奇趣故事匣 来了
前端·harmonyos·客户端
幽蓝计划12 小时前
HarmonyOS NEXT仓颉开发语言实战案例:电影App
华为·harmonyos
HMS Core14 小时前
HarmonyOS免密认证方案 助力应用登录安全升级
安全·华为·harmonyos
生如夏花℡14 小时前
HarmonyOS学习记录3
学习·ubuntu·harmonyos
伍哥的传说14 小时前
鸿蒙系统(HarmonyOS)应用开发之手势锁屏密码锁(PatternLock)
前端·华为·前端框架·harmonyos·鸿蒙
遇到困难睡大觉哈哈1 天前
HarmonyOS 公共事件机制介绍以及多进程之间的通信实现(9000字详解)
华为·harmonyos
幽蓝计划1 天前
HarmonyOS NEXT仓颉开发语言实战案例:外卖App
开发语言·harmonyos
伍哥的传说1 天前
鸿蒙系统(HarmonyOS)应用开发之实现电子签名效果
开发语言·前端·华为·harmonyos·鸿蒙·鸿蒙系统
Georgewu1 天前
【HarmonyOS】应用开发拖拽功能详解
harmonyos