HarmonyOS 鸿蒙Next:Observed类中的数组被修改,其对应的UI无法刷新?
HarmonyOS 鸿蒙Next:Observed类中的数组被修改,其对应的UI无法刷新?
基本逻辑:现在业务中,有个属性是被选中的月份数组(假设为month),month的值显示在控件A中,点击A之后弹出sheet可以修改month,其变化会映射到控件A中。这个month是放在一个被@Observed装饰的类BestTime中的,子控件A中通过ObjectLink接收BestTime的对象
问题:当我直接修改month的时候,控件A中的内容不会更新;如果修改了BestTime中其他基础类型属性(如某个字符串),A中month的内容才会更新。
求助:有什么办法在修改month后,将变化直接传递到A吗
代码如下:
[@Observed](/user/Observed)
export class BestTime {
month: number[]; // 需要被修改的属性
timeInDay: string[];
constructor(month: number[], timeInDay: string[]) {
this.month = month;
this.timeInDay = timeInDay;
}
}
// 承载month属性的控件
@Component
export struct A {
@ObjectLink bestTime: BestTime
@State private sheetState: boolean = false
@Builder
private buildEditBestTimeSheet() {
EditBestTimeSheet({ bestTime: this.bestTime })
}
build() {
Column({ space: PaddingValue.small }) {
Text('选择月份')
Row() {
// 显示被选中的月份。
// 此处不会随month被修改而变化
Text(JSON.stringify(this.bestTime.month)).layoutWeight(SizeValue.fullWeight)
RightButton()
}
.width(SizeValue.fullWidth)
.backgroundColor(colorBgPrimary)
.padding(PaddingValue.small)
.borderRadius(RadiusValue.small)
.bindSheet($$this.sheetState, this.buildEditBestTimeSheet,
bottomSheetOptionWithTitle('选择月份'))
.onClick(() => this.sheetState = true)
// 使用列表形式也不会跟随变化
List(){
ForEach(
this.bestTime.month,
(item: number) => {
ListItem() {
Text(item.toString())
}
}
)
}.width(SizeValue.fullWidth)
.height(32)
}
.width(SizeValue.fullWidth)
.alignItems(HorizontalAlign.Start)
.padding(PaddingValue.horizontalNormalPadding)
}
}
// 点击控件A之后弹出的sheet
@Component
export struct EditBestTimeSheet {
@ObjectLink bestTime: BestTime
private monthList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
// 修改月份
private selectItem(item: number, isOn: boolean) {
const current = this.bestTime.month
const index = current.indexOf(item)
if (index < 0 && isOn) {
current.push(item)
this.bestTime.month = current
return
}
if (index >= 0 && !isOn) {
current.slice(index, 1)
this.bestTime.month = current
return
}
}
build() {
Column({ space: PaddingValue.small }) {
Text('选择月份')
// 月份选择器
Flex({ wrap: FlexWrap.Wrap, space: { main: LengthMetrics.vp(PaddingValue.small) } }) {
ForEach(
this.monthList,
(item: number) => {
Toggle({ type: ToggleType.Button, isOn: this.bestTime.month.indexOf(item) >= 0 }) {
Text(item.toString())
.fontColor(this.bestTime.month.indexOf(item) >= 0 ? colorBgPrimary : colorContent)
.fontSize(12)
}.padding(PaddingValue.small)
.selectedColor(colorPrimary)
.onChange((isOn: boolean) => {
console.log(`select ${item}, state: ${isOn}`)
this.selectItem(item, isOn)
})
},
(item: number) => item.toString()
)
}
}
.padding(PaddingValue.horizontalNormalPadding)
}
}
更多关于HarmonyOS 鸿蒙Next:Observed类中的数组被修改,其对应的UI无法刷新?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
定义一个@Observed 修饰的数组。extends Array<Object>
更多关于HarmonyOS 鸿蒙Next:Observed类中的数组被修改,其对应的UI无法刷新?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
但是把弹窗的ui抽象成一个新的Component,把Observed类传递到这个新的Component,在弹窗中修改属性后可以单向同步回父控件内,无法更新弹窗内的ui。也就是说Observed的双向同步无法在bindSheet绑定的新Component中生效,只有把弹窗的ui和被绑定了bindSheet的ui放在同一个Component中共享Observed才可以双向同步,请问这个问题有就解决办法吗
解决了,在buildSheet
的绑定中添加一层Column
包裹到ui
就可以了:
解决了,在buildSheet
的绑定中添加一层Column
包裹到ui
就可以了:
原生的数组修改数组属性时是不会被监听的,ui也就不会被刷新。可以按照二楼的方法解决,或者仔细看下开发文档
但是把弹窗的ui抽象成一个新的Component,把Observed类传递到这个新的Component,在弹窗中修改属性后可以单向同步回父控件内,无法更新弹窗内的ui。也就是说Observed的双向同步无法在bindSheet绑定的新Component中生效,只有把弹窗的ui和被绑定了bindSheet的ui放在同一个Component中共享Observed才可以双向同步,请问这个问题有就解决办法吗
解决了,在buildSheet
的绑定中添加一层Column
包裹到ui
就可以了:
解决了,在buildSheet
的绑定中添加一层Column
包裹到ui
就可以了:
实现一个数组
class ObservedArray<T> extends Array<T> {}
然后month的类型设置为ObservedArray,初始化时new一个ObservedArray,
但是把弹窗的ui抽象成一个新的Component,把Observed类传递到这个新的Component,在弹窗中修改属性后可以单向同步回父控件内,无法更新弹窗内的ui。也就是说Observed的双向同步无法在bindSheet绑定的新Component中生效,只有把弹窗的ui和被绑定了bindSheet的ui放在同一个Component中共享Observed才可以双向同步,请问这个问题有就解决办法吗
解决了,在buildSheet的绑定中添加一层Column包裹到ui就可以了:
@Builder private buildEditBestTimeSheet() { Column(){ EditBestTimeSheet({ bestTime: this.bestTime }) } }
不是很清楚,这是我之前回复过的帖子,可以看下是否符合你的需求
可以按照楼上的方法解决,新建一个带Observed
类继承Array
。或者直接创建新数组传递给Observed
中的属性也可以。
在HarmonyOS(鸿蒙)开发中,若Observed类中的数组被修改后,UI没有刷新,这通常是因为数据绑定机制未能正确检测到数组内容的变化。HarmonyOS的数据绑定依赖于Observable对象的属性变化通知。对于数组或列表类型的数据,直接修改其内容(如通过索引赋值)通常不会触发属性变更通知,因为数组对象本身的引用没有改变。
解决这一问题的方法通常涉及以下几点:
-
使用ObservableList或类似容器:HarmonyOS可能提供了特定的容器类(如ObservableList),用于自动检测内容变化并通知UI更新。检查文档并考虑使用这些类代替普通数组。
-
手动通知变更:如果使用的是普通数组,当数组内容变化时,需要手动调用Observable对象的notifyPropertyChanged方法(或类似机制),并传递正确的属性名以触发UI刷新。
-
替换整个数组:作为替代方案,当数组内容需要更新时,可以创建一个新数组并替换旧数组。这将触发对象引用的变化,从而可能触发UI更新。
如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html,