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

相关推荐
lqj_本人2 分钟前
鸿蒙next选择 Flutter 开发跨平台应用的原因
flutter·华为·harmonyos
lqj_本人4 分钟前
使用 Flutter 绘制一个棋盘
harmonyos
lqj_本人3 小时前
Flutter&鸿蒙next 状态管理框架对比分析
flutter·华为·harmonyos
青瓷看世界4 小时前
华为HarmonyOS打造开放、合规的广告生态 - 插屏广告
华为·harmonyos·广告投放
青瓷看世界5 小时前
华为HarmonyOS借助AR引擎帮助应用实现虚拟与现实交互的能力2-管理AR会话
华为·ar·harmonyos·虚拟现实
2301_795558645 小时前
鸿蒙的进化史
华为·harmonyos
Swift社区5 小时前
HarmonyOS App 购物助手工具的开发与设计
harmonyos·arkts·arkui
lqj_本人7 小时前
Flutter&鸿蒙next 实现一个计算器应用
华为·harmonyos
呆萌很10 小时前
HCIP-HarmonyOS Application Developer V1.0 笔记(五)
harmonyos
fanstuck10 小时前
互联网技术净土?原生鸿蒙开启全新技术征程
华为·harmonyos·鸿蒙·鸿蒙系统