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