HarmonyOS鸿蒙Next中通过class-transformer解析为一个泛型类的对象后,@ObservedV2修饰类中被@Trace修饰的变量改变后不会刷新
HarmonyOS鸿蒙Next中通过class-transformer解析为一个泛型类的对象后,@ObservedV2修饰类中被@Trace修饰的变量改变后不会刷新
这是实体类:
class BaseEntity<T>{
code:number
message:string
body:T|undefined
constructor(code: number, message: string, body: T | undefined) {
this.code = code;
this.message = message;
this.body = body;
}
}
[@ObservedV2](/user/ObservedV2)
class UserV2 {
id: number
[@Trace](/user/Trace) username: string
[@Trace](/user/Trace) age: number
constructor(id: number,username: string,age:number) {
this.id = id;
this.username = username;
this.age = age
}
}
这个在ts中通过class-transformer解析json字符串
export function parseJsonToClass<T>(jsonString: string, classType: new (...args: any[]) => T): T {
const jsonObj = JSON.parse(jsonString);
return plainToInstance(classType, jsonObj);
}
解析不是泛型类型的,修改user对象被@Trace 装饰的变量可以刷新UI:
@Local
user:UserV2 = new UserV2(0,'',0)
aboutToAppear(): void {
let json = '{"id": 1, "username": "alice", "age":5}';
this.user = parseJsonToClass<UserV2>(json,UserV2)
}
但是解析的是泛型类型的,修改user对象被@Trace 装饰的变量就不能刷新UI了
let jsonStr = '{"code":0,"message":"success","body":{"id": 1, "username": "alice","age":5}}';
let entity = parseJsonToClass<BaseEntity<UserV2>>(jsonStr,BaseEntity)
Logger.info(JSON.stringify(entity.body))
if(entity.body){
this.user = entity.body
}
更多关于HarmonyOS鸿蒙Next中通过class-transformer解析为一个泛型类的对象后,@ObservedV2修饰类中被@Trace修饰的变量改变后不会刷新的实战教程也可以访问 https://www.itying.com/category-93-b0.html
使用@ObservedV2与@Trace装饰器的类,需通过new操作符实例化后,才具备被观测变化的能力。
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-observedv2-and-trace# 概述
可以先解析body,然后再把body设置到这个BaseEntity中去
在这ts的文件新增一个解析的方法:
/**
*
* @param jsonString json字符串
* @param classType json最终转换成的class类型
* @param bodyName body(泛型)字段的名称
* @param bodyClassType body(泛型)的class类型
* @returns
*/
export function parseJson<T,V>(jsonString: string, classType:ClassConstructor<T>,bodyName:string,bodyClassType:ClassConstructor<V>):T{
const jsonObj = JSON.parse(jsonString);
const jsonBodyObj = jsonObj[bodyName];
//先解析body这个泛型对象
const body:V = plainToInstance(bodyClassType,jsonBodyObj);
//再解析整个,排除body字段
const result:T = plainToInstance(classType, jsonObj,{excludePrefixes:[bodyName]});
result[bodyName] = body
return result;
}
调用:
let entity = parseJson<BaseEntity<UserV2>,UserV2>(jsonStr,BaseEntity,'body',UserV2)
Logger.info(JSON.stringify(entity.body))
if(entity.body){
this.user = entity.body
}
更多关于HarmonyOS鸿蒙Next中通过class-transformer解析为一个泛型类的对象后,@ObservedV2修饰类中被@Trace修饰的变量改变后不会刷新的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
还有个办法,当转换包含嵌套对象的对象时,需要使用@Type
装饰器指定嵌套对象的类型,但是这个类型是泛型 T
//T是泛型这里会报错
但是class-transformer 还可以动态的配置Type:
const targetMap:TargetMap = {
target:BaseEntity,
properties: {
'body':UserV2
},
};
let entity =plainToInstance<BaseEntity<UserV2>,ESObject>(BaseEntity,JSON.parse(jsonStr),{targetMaps:[targetMap]})
Logger.info(JSON.stringify(entity.body))//可以打印一下,被@Trace修饰的字段名称是以__ob_为开头, 证明是成功的
在HarmonyOS鸿蒙Next中,@ObservedV2
用于标记可观察的类,@Trace
用于标记需要跟踪的变量。当通过class-transformer
解析为泛型类对象后,@Trace
修饰的变量改变时,@ObservedV2
修饰的类不会自动刷新。这是因为class-transformer
生成的实例可能未正确绑定到鸿蒙的响应式系统中,导致状态更新未触发UI刷新。
在HarmonyOS Next中,当使用class-transformer解析泛型类时,@ObservedV2和@Trace的响应式机制可能会失效。这是因为:
-
泛型类型在运行时会被擦除,导致plainToInstance无法正确保留UserV2的装饰器信息
-
解决方案建议:
-
直接使用具体类型而非泛型进行转换
-
在赋值前手动创建新的UserV2实例:
if(entity.body){ this.user = new UserV2(entity.body.id, entity.body.username, entity.body.age) }
- 或者为BaseEntity添加@ObservedV2装饰器:
[@ObservedV2](/user/ObservedV2)
class BaseEntity<T>{
//...
}
这样可以确保响应式系统能正确追踪嵌套对象的变化。