HarmonyOS 鸿蒙Next中对象的被观察字段显示不为空,实际字段却是空?

HarmonyOS 鸿蒙Next中对象的被观察字段显示不为空,实际字段却是空? debug调试时候发现webviewPageConfig对象存在字段_ob_preferredOrientation =0(图一所示), 但是 webPageConfig.preferredOrientation却是undefined(图二所示),这是为啥呢?

cke_131.png

cke_12116.png

附上webviewPageConfig的代码

export interface WebviewParam {
  url: string;
  id?: string;
  fullscreen?: boolean;
  showTitle?: boolean;
  titleStyle?: WebviewTitleStyle;
  jsProxyName?: string;
  preferredOrientation?: window.Orientation;
  showCloseIcon?: boolean;
  showIconAtRight?: boolean;
  width?: Length;
  height?: Length;
  bgColor?: ResourceColor;
  webCallback?:WebCallback

}

@ObservedV2
export class WebviewPageConfig {
  @Trace
  url: string
  @Trace
  id: string
  @Trace
  fullscreen: boolean
  @Trace
  showTitle: boolean
  @Trace
  titleStyle?: WebviewTitleStyle
  @Trace
  jsProxyName: string
  @Trace
  preferredOrientation: window.Orientation
  @Trace
  showCloseIcon: boolean
  @Trace
  showIconAtRight: boolean
  @Trace
  width: Length;
  @Trace
  height: Length;
  @Trace
  bgColor: ResourceColor;
  webCallback:WebCallback

  constructor(webviewParam: WebviewParam) {
    this.url = webviewParam.url;
    this.id = webviewParam.id ?? cryptoUtils.md5(this.url.toString());
    this.fullscreen = webviewParam.fullscreen ?? true;
    this.showTitle = webviewParam.showTitle ?? true;
    this.titleStyle = webviewParam.titleStyle;
    this.jsProxyName = webviewParam.jsProxyName ?? 'bridge';
    this.preferredOrientation = webviewParam.preferredOrientation ?? window.Orientation.UNSPECIFIED;
    this.showCloseIcon = webviewParam.showCloseIcon ?? false;
    this.showIconAtRight = webviewParam.showIconAtRight ?? true;
    this.width = webviewParam.width ?? '100%';
    this.height = webviewParam.height ?? '100%';
    this.bgColor = webviewParam.bgColor ?? Color.White;
    this.webCallback = webviewParam.webCallback??{}
  }
}

更多关于HarmonyOS 鸿蒙Next中对象的被观察字段显示不为空,实际字段却是空?的实战教程也可以访问 https://www.itying.com/category-93-b0.html

10 回复

通过@ObservedV2创建的类实例实际是被Proxy包装的响应式对象

直接访问preferredOrientation时实际调用的是代理getter,若未正确初始化则返回undefined

使用@Trace装饰的属性会被自动添加__ob_前缀的代理字段(实际存储变量名为__ob_preferredOrientation)

调试工具显示的_ob_preferredOrientation是代理系统生成的中间变量,而原始属性名被代理机制覆盖

更多关于HarmonyOS 鸿蒙Next中对象的被观察字段显示不为空,实际字段却是空?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


直接访问preferredOrientation时实际调用的是代理getter—> 代理getter返回的不是_ob_preferredOrientation的值吗,

个人觉得应该是这样:_ob_preferredOrientation是preferredOrientation系统生成getter和setter方法中为原有变量名添加"_ob"的前缀代理对象。所以DeBug时直接访问preferredOrientation是undefined,_ob_preferredOrientation才是实际的。

但是实际代码执行时候也是跟debug看到一样,走了preferredOrientation = undefined的逻辑,

  1. 装饰器的属性重写@ObservedV2(通常用于响应式)和 @Trace(用于日志追踪)会拦截原始属性,通过重命名(如加 _ob_ 前缀)来实现功能,此时原始字段名 preferredOrientation 已不再指向实际数据。
  2. 接口与类的字段初始化差异:虽然 WebviewParam 接口将 preferredOrientation 定义为可选,但类的构造函数中用 ?? 给了默认值 window.Orientation.UNSPECIFIED,理论上不会未定义,进一步说明是装饰器修改了属性访问方式。

preferredOrientation按道理是指向_ob_preferredOrientation的了,那么_ob_preferredOrientation = 0的前提下,为啥preferredOrientation还是undefined呢?

闭眼当没看见,

代码执行不符合预期,才发现这个问题,

在HarmonyOS Next中,对象的被观察字段(@Observed/@Tracked)显示不为空但实际为空,通常是由于数据绑定与UI更新不同步导致。检查是否在异步操作后未触发UI刷新,或状态管理未正确响应字段变更。确保使用@Tracked装饰器标记可变字段,并在ArkUI的声明式UI中正确绑定数据源。

这是一个典型的ArkTS/ETS中@ObservedV2@Trace装饰器与调试器显示差异的问题。

在调试器中看到的_ob_preferredOrientation = 0是ArkUI框架为被观察对象生成的内部代理属性。当使用@ObservedV2装饰类,并用@Trace装饰字段时,框架会为这些字段创建响应式代理。_ob_前缀的属性是框架内部用于跟踪状态变化的代理值,而不是原始字段的直接映射。

出现webPageConfig.preferredOrientationundefined的可能原因:

  1. 构造函数初始化问题:检查传入的webviewParam参数。如果webviewParam.preferredOrientationundefined,且window.Orientation.UNSPECIFIED可能在某些情况下也被视为undefined或0,这可能导致实际字段未正确初始化。

  2. 代理对象访问时机:调试器可能在不同时间点捕获对象状态。直接访问字段时,如果该字段尚未通过响应式系统初始化,可能会返回undefined,而内部代理值已设置为默认值0。

  3. 类型定义问题:确认window.Orientation.UNSPECIFIED的值定义。如果它的值是0,在JavaScript/TypeScript中,0有时会在条件判断中被当作false处理,但本身不是undefined

建议检查:

  • 传入构造函数的实际参数值
  • window.Orientation.UNSPECIFIED的具体数值定义
  • 确保在访问preferredOrientation前,对象已完全初始化

这种差异通常不影响运行时行为,因为框架内部使用的是代理值(_ob_前缀的属性)来进行响应式更新。

回到顶部