HarmonyOS鸿蒙Next中V1状态管理能实现监听map存入的对象类型属性吗?
HarmonyOS鸿蒙Next中V1状态管理能实现监听map存入的对象类型属性吗? V1状态管理能实现监听 map存入的对象类型属性 吗? 类似 map<string,GattClientManager>中监听GattClientManager的属性变化
监听map存入的对象属性类型得用V2
【背景知识】 @ObservedV2:为了在自定义组件中使用V2版本状态变量装饰器的能力,开发者可以使用@ComponentV2装饰器装饰自定义组件。 @Trace:用于装饰类中的属性,使得被装饰的属性具有深度观测的能力。 @Local:表示组件内部的状态,使得自定义组件内部的变量具有观测变化的能力。 @Monitor:用于监听状态变量修改,使得状态变量具有深度监听的能力。
【解决方案】 将数据源转化为数组,监听数组的变化。
// 数据管理 类 Store
[@ObservedV2](/user/ObservedV2)
export class Member {
[@Trace](/user/Trace) membersMedia: Record<string, MembersMedia> = { 'test': new MembersMedia() };
setMembersMedia(data: MembersMedia) {
if (this.membersMedia[data.id]) {
// 兼容初始有 默认值 test的场景。
this.membersMedia[data.id].id = data.id;
this.membersMedia[data.id].name = data.name;
} else {
this.membersMedia[data.id] = new MembersMedia();
this.membersMedia[data.id].id = data.id;
this.membersMedia[data.id].name = data.name;
}
}
updateMembersMedia(data: MembersMedia) {
if (this.membersMedia[data.id]) {
this.membersMedia[data.id].id = data.id;
this.membersMedia[data.id].name = data.name;
} else {
this.membersMedia[data.id] = new MembersMedia();
this.membersMedia[data.id].id = data.id;
this.membersMedia[data.id].name = data.name;
}
}
deleteMembersMedia(data: MembersMedia) {
let tempObj: Record<string, MembersMedia> = {};
if (this.membersMedia[data.id] && JSON.stringify(this.membersMedia[data.id]) !== '{}') {
Object.keys(this.membersMedia).forEach(key => {
if (key !== data.id) {
tempObj[key] = this.membersMedia[key];
}
});
this.membersMedia = tempObj;
console.log('deletemembersMedia after:: this.membersMedia:', JSON.stringify(this.membersMedia));
}
}
}
[@ObservedV2](/user/ObservedV2)
class MembersMedia {
[@Trace](/user/Trace) name?: string = '初始值';
[@Trace](/user/Trace) id: string = '000';
}
通过@Monitor(‘member’)监听的member变化并未打印数据变化,创建一个memberArray数组,用数组作为ForEach的参数,可以监听到数据变化。
let mem = new Member();
export default mem;
@Entry
[@ComponentV2](/user/ComponentV2)
struct Index {
[@Local](/user/Local) message: string = 'Hello World';
[@Local](/user/Local) member: Member = mem;
[@Local](/user/Local) memberArray: string[] = Object.keys(this.member.membersMedia);
aboutToAppear(): void {
console.log(Object.keys(this.member.membersMedia).toString());
}
[@Monitor](/user/Monitor)('member')
onchange() {
console.log('数据有变化1');
}
build() {
Column() {
Column() {
ForEach(this.memberArray, (key: string) => {
Text((this.member.membersMedia[key]?.id + this.member.membersMedia[key]?.name) || 'default')
.id('HelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.margin(10)
.border({
width: 1,
color: Color.Red
});
});
};
Blank()
.height(50);
Button('set test')
.margin(10)
.onClick(() => {
let test: MembersMedia = { id: 'test', name: '新增-111' };
this.member.setMembersMedia(test);
console.log('get test 1111::', JSON.stringify(this.member.membersMedia[test.id]));
});
Button('update test')
.margin(10)
.onClick(() => {
let test: MembersMedia = { id: 'test', name: '修改-111' };
this.member.updateMembersMedia(test);
console.log('get test 2222::', JSON.stringify(this.member.membersMedia[test.id]));
});
Button('set test1')
.margin(10)
.onClick(() => {
let test1: MembersMedia = { id: 'test1', name: '新增-222' };
this.member.setMembersMedia(test1);
this.memberArray = Object.keys(this.member.membersMedia);
console.log('get test1 1111::', JSON.stringify(this.member.membersMedia[test1.id]));
});
Button('update test1')
.margin(10)
.onClick(() => {
let test1: MembersMedia = { id: 'test1', name: '修改-222' };
this.member.updateMembersMedia(test1);
console.log('get test1 2222::', JSON.stringify(this.member.membersMedia[test1.id]));
});
Button('delete test1')
.margin(10)
.onClick(() => {
let test1: MembersMedia = { id: 'test1' };
this.member.deleteMembersMedia(test1);
this.memberArray = Object.keys(this.member.membersMedia);
console.log('get test1 3333::', JSON.stringify(this.member.membersMedia[test1.id]));
});
}
.height('100%')
.width('100%');
}
}
更多关于HarmonyOS鸿蒙Next中V1状态管理能实现监听map存入的对象类型属性吗?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
应该是不行的,深度监听可以使用V2状态管理,例如
@ObservedV2
class testCls{
@Trace data: map<string,GattClientManager>
}
官方文档:类属性变化观测
在HarmonyOS Next中,V1状态管理支持监听Map中存储的对象类型属性变化。通过使用@Observed和@ObjectLink装饰器,可以监测对象内部属性的变更。当Map中的对象属性被修改时,系统会自动触发UI更新。此机制适用于对象属性级别的细粒度监听,确保状态与视图同步。
在HarmonyOS Next的V1状态管理(如AppStorage或LocalStorage)中,直接监听Map中存储的对象类型属性变化目前存在限制。V1状态管理主要支持基础数据类型(如string、number、boolean)的响应式更新,或通过@Observed和@ObjectLink装饰器监听简单对象的属性变化。
对于Map<string, GattClientManager>这类场景,若需监听GattClientManager实例的属性变化,需满足以下条件:
- GattClientManager类需用@Observed装饰器标记,使其属性可被监听。
- 使用@ObjectLink装饰变量,在组件中关联具体对象实例。
但直接监听Map中动态键值对的对象属性变化较为复杂,V1状态管理无法自动追踪Map内对象属性的变更。建议通过以下方式实现类似功能:
- 将GattClientManager的关键属性提取到独立状态变量(如AppStorage),通过手动更新触发监听。
- 在GattClientManager内部实现自定义事件通知,结合业务逻辑主动触发UI更新。
若需更细粒度监听,可关注HarmonyOS Next后续版本对状态管理的增强能力。

