HarmonyOS 鸿蒙Next中@Observed 与 class

HarmonyOS 鸿蒙Next中@Observed 与 class

我现在有一个class 添加了[@Observed](/user/Observed)注解。 现在我因为业务需要将这个class实例化然后通过emitter通知给其他页面使用,因为这个[@Observed](/user/Observed)导致new出来的class时proxy类型的,在emitter的时候proxy对象被丢弃了。这个有什么好像解决方案么?

[@Observed](/user/Observed)
export class WorkAppGroupBean extends WorkBaseBean{
  id:string = '';
  children:WorkBaseBean[] = [];
  icon:string = '';
  parentId:string = '';
  redMark:boolean = false;
  isAdd:boolean = false;
}

@Component
export struct AppSearchPage {
  aboutToAppear(): void {
    this.notifyEvent()
  }
  notifyEvent(){
    emitter.on(AllAppCentersEvent.name,(res: emitter.GenericEventData<AllAppCentersEvent>)=>{
      if(res && res.data){
        LOGGER.info("AppSearchPage",JSON.stringify(res))
      }else{
        LOGGER.info("AppSearchPage","JSON.stringify(res)")
      }

    });
  }
  build() {
    NavDestination(){
      Text("首页!!!!!!!!!!!!!")
     
      Divider()
      Text('插入Group')
      Column(){
        TextInput({text:$$this.textG}).width(BaseConstants.FULL_WIDTH)
        Blank().height(5)
        Button("插入数据").onClick(()=>{
          let gb = new WorkAppGroupBean();
          let eventData: emitter.GenericEventData<AllAppCentersEvent> = {
                data: new AllAppCentersEvent(gb)
              }
          emitter.emit(AllAppCentersEvent.name,eventData );
        })
      }.margin({bottom:5})
      
    }.hideTitleBar(true)
  }
}

![cke_15925.png](data-originheight=“307” data-originwidth=“603”)

![cke_18380.png](data-originheight=“180” data-originwidth=“906”)


更多关于HarmonyOS 鸿蒙Next中@Observed 与 class的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复
@Observed 的本质是通过 **Proxy 代理** 实现对象属性的监听(当属性变化时自动触发 UI 更新)。而 `emitter` 在传递数据时,会对对象进行序列化 / 反序列化,这个过程会剥离 Proxy 代理层,导致接收方拿到的是被代理前的原始对象(或不完整数据)。

必须用 emitter 吗?你要不试试全局状态管理

更多关于HarmonyOS 鸿蒙Next中@Observed 与 class的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


现在是具体的业务对象是不完整,没有的。
我尝试用了新建一个未添加@Observed的相同属性的类来处理,但是总感觉有那么一点难受,每次当需要使用的时候需要转换多次。
鸿蒙会不会有什么api将proxy装饰的类,可以将proxy分离,得到真是的原始业务对象,

在HarmonyOS鸿蒙Next中,@Observed是ArkUI框架的装饰器,用于标记类,使其具备响应式能力。当@Observed装饰的类属性变化时,UI会自动更新。class是TypeScript/JavaScript的基础关键字,用于定义类结构。二者结合时,@Observed装饰的类成为数据源,驱动UI渲染。例如:

@Observed
class Person {
  name: string = '';
  age: number = 0;
}

需注意:@Observed仅修饰类,属性需配合@ObjectLink@Prop在组件中使用。

在HarmonyOS Next中,@Observed注解会将被装饰的类转换为Proxy对象以实现响应式更新。当通过emitter传递这类对象时,Proxy特性确实可能丢失。

解决方案建议:

  1. 在传递前手动转换对象为普通JS对象:
let plainObject = JSON.parse(JSON.stringify(proxyObject));
emitter.emit(eventName, plainObject);
  1. 接收方重新包装对象:
emitter.on(eventName, (data) => {
  const restoredObj = new WorkAppGroupBean();
  Object.assign(restoredObj, data);
  // 使用restoredObj
});
  1. 考虑使用深拷贝工具函数来保留对象结构但去除Proxy特性

  2. 如果业务允许,可以直接传递原始数据而非整个类实例

注意:这些方案都会失去响应式特性,接收方需要根据业务需求决定是否重新添加@Observed装饰。

回到顶部