【HarmonyOS 5】makeObserved接口详解

简介: 【HarmonyOS 5】makeObserved接口详解


##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财#

一、makeObserved接口是什么?

makeObserved 接口(API version 12 起可用)用于将非观察数据转为可观察数据,适用于三方包类、@Sendable 装饰的类、JSON.parse 返回的对象、collections.Array/Set/Map 等场景。

不支持 undefined和null类型。以及V1 状态装饰器(@State/@Prop)及已被观察的数据,避免双重代理。主要处理的是Object类型,非Object类型,例如基本数据类型number这种,都不支持。

需要注意的是,makeObserved主要针对的是V2的使用场景。因为它是为了解决 @Trace/@ObservedV2 无法覆盖的痛点观察需求。比如从网络请求返回的JSON对象,需要在UI上进行观测操作。就可使用makeObserved。所以V1使用@State就可解决的问题,不用考虑这个。

二、makeObserved如何使用?

(1)接口调用
使用及其简单,只需要导入import { UIUtils } from '@kit.ArkUI'进行接口调用接口。麻烦的是识别你的入参是否支持观测监听。

import { UIUtils } from '@kit.ArkUI';
class UserInfo {
  id: number = 0;
}
let observedInfo: UserInfo = UIUtils.makeObserved(new UserInfo());

(2)可从操作的业务场景进行区分,符合以下三种场景一般可操作:
1、三方SDK包中的数据类,这种情况下需要UI可监测,因为无法手动添加@Trace,一般可支持。
【该场景较为简单,参考上面示例即可】

2、@Sendable装饰的类,因为禁止动态修改属性,一般可支持。

import { taskpool } from '@kit.ArkTS';
import { UIUtils } from '@kit.ArkUI';
// 定义@Sendable装饰的类(支持子线程传递)
@Sendable
class UserInfo {
  userId: number = 0;
  username: string = 'Guest';
  score: number = 0;
  isOnline: boolean = false;
  // 构造函数初始化数据
  constructor(userId: number, username: string) {
    this.userId = userId;
    this.username = username;
  }
}
// 子线程任务:模拟数据处理(如网络请求/复杂计算)
@Concurrent
function processDataInThread(userId: number): UserInfo {
  // 模拟耗时操作(子线程执行)
  let result = new UserInfo(userId, 'Loading...');
  setTimeout(() => {
    // 模拟数据更新
    result.score = Math.floor(Math.random() * 100);
    result.isOnline = true;
  }, 1000);
  return result;
}
@Entry
@ComponentV2
struct SendableMakeObservedDemo {
  // 主线程可观察数据:通过makeObserved包装@Sendable对象
  @Local observedUser: UserInfo = UIUtils.makeObserved(new UserInfo(-1, '未登录'));
  build() {
    Column({ space: 20 })
      .width('100%')
      .padding(30) {
        
        Text('@Sendable + makeObserved 演示')
          .fontSize(24)
          .fontWeight(500)
        
        // 显示用户信息
        Text(`用户ID: ${this.observedUser.userId}`)
          .fontSize(18)
        
        Text(`用户名: ${this.observedUser.username}`)
          .fontSize(18)
        
        Text(`分数: ${this.observedUser.score}`)
          .fontSize(18)
        
        Text(`在线状态: ${this.observedUser.isOnline ? '在线' : '离线'}`)
          .fontSize(18)
        
        // 触发子线程任务的按钮
        Button('加载用户数据(子线程处理)')
          .onClick(() => {
            // 在子线程执行数据处理
            taskpool.execute(processDataInThread, 1001).then((user: UserInfo) => {
              // 子线程返回的@Sendable对象在主线程重新包装为可观察数据
              this.observedUser = UIUtils.makeObserved(user);
            });
          })
        
        // 本地修改数据的按钮(演示可观察性)
        Button('本地增加分数')
          .onClick(() => {
            this.observedUser.score += 10; // 直接修改属性,触发UI刷新
          })
      }
  }
}


3、 JSON.parse返回的匿名对象,一般是网络请求反馈,一般可支持。

import { UIUtils } from '@kit.ArkUI';
import { JSON } from '@kit.ArkTS';
// 定义 JSON 数据结构(示例接口)
interface UserData {
  name: string;
  age: number;
  email: string;
}
@Entry
@ComponentV2
struct JsonMakeObservedDemo {
  // 原始 JSON 字符串
  private rawJson: string = '{"name": "Alice", "age": 25, "email": "alice@example.com"}';
  
  // 使用 makeObserved 包装 JSON.parse 返回的对象
  @Local observedData: UserData = UIUtils.makeObserved(JSON.parse(this.rawJson) as UserData);
  build() {
    Column({ space: 30 })
      .width('100%')
      .padding(30) {
        
        // 显示 JSON 数据
        Text('JSON 可观察数据演示')
          .fontSize(24)
          .fontWeight(500)
        
        Text(`姓名: ${this.observedData.name}`)
          .fontSize(18)
        
        Text(`年龄: ${this.observedData.age}`)
          .fontSize(18)
        
        Text(`邮箱: ${this.observedData.email}`)
          .fontSize(18)
        
        // 修改姓名的按钮
        Button('修改姓名为 "Bob"')
          .onClick(() => {
            this.observedData.name = 'Bob'; // 直接修改属性,触发 UI 刷新
          })
        
        // 修改年龄的按钮
        Button('年龄 +1')
          .onClick(() => {
            this.observedData.age++; // 数值类型修改,触发 UI 刷新
          })
        
        // 重置为原始数据的按钮
        Button('重置数据')
          .onClick(() => {
            // 重新解析 JSON 并包装为可观察数据
            this.observedData = UIUtils.makeObserved(JSON.parse(this.rawJson) as UserData);
          })
      }
  }
}


三、注意

  1. getTarget问题
    通过getTarget获取原始对象后修改属性,不会触发UI刷新(需操作代理对象)
  2. 兼容性错误
    与@State等V1装饰器混用会抛异常,需使用V2装饰器(@Local/@Provide等)
目录
相关文章
|
移动开发 安全 Android开发
【HarmonyOS 5】鸿蒙mPaaS详解
mPaaS 是 Mobile Platform as a Service 的缩写,即移动开发平台。
291 0
|
缓存 数据安全/隐私保护 JavaScript
【HarmonyOS 5】鸿蒙页面和组件生命周期函数
【HarmonyOS 5】鸿蒙页面和组件生命周期函数
176 0
|
4月前
|
API 开发工具 容器
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
FA大概是API7之前的开发模型。所谓的开发模型,值得是创建鸿蒙开发工程后,你在什么样子的系统容器和接口上进行开发。 当初我在开发OpenHarmony的时候,最早用的就是FA模型,正是因为FA模型在开发过程中的诸多不方便,大概在API8时,官方推出了Stage模型,进行初步替代。 Stage模型,见名知意,是在系统提供的舞台容器上,进行应用的开发。整理更新的低耦合,高内聚。应用进程的管理也更加合理高效。 本文主要针对Stage模型与FA模型的区别。以及Stage模型如何获取上下文作出讲解。
220 0
|
4月前
|
物联网 开发工具
【HarmonyOS】鸿蒙应用蓝牙功能实现 (二)
【HarmonyOS】鸿蒙应用蓝牙功能实现 (二)
121 9
【HarmonyOS】鸿蒙应用蓝牙功能实现 (二)
|
4月前
|
存储 安全 API
【HarmonyOS 5】鸿蒙应用隐私保护详解
【HarmonyOS 5】鸿蒙应用隐私保护详解
163 1
|
4月前
|
开发工具
【HarmonyOS 5】使用openCustomDialog如何禁止手势关闭的方案
openCustomDialog提供了onWillDismiss回调函数,当用户尝试通过滑动、点击外部、返回键等操作关闭弹窗时,会触发该回调。通过在回调中判断关闭原因并拦截操作,即可实现禁止手势关闭的效果。
125 1
|
4月前
|
传感器 安全 物联网
【HarmonyOS 5】鸿蒙分布式协同应用开发详解
为什么需要分布式协同应用? 首先是因为当今社会,围绕电子产品生态,人们迫切希望,周边的电子设备可以协同操作。例如手机,手表,电视机,汽车,甚至是各种家电产品。 从2015年到如今,手机和pc等老牌电子产品的设备数趋于稳定,其他IoT设备稳步增长。可见人均所拥有的的电子产品的个数,在迅速增加。
160 0
|
4月前
|
前端开发 JavaScript API
【HarmonyOS 5】鸿蒙跨平台开发方案详解(一)
2025年是鸿蒙生态迎来关键发展期。根据前几天的2025 HDC数据显示,鸿蒙原生应用数量已从2024年的2000款增长至5000款,微信鸿蒙版安装量突破1.2亿,公安部交管系统完成全国300城鸿蒙适配。
302 1
|
4月前
|
监控 JavaScript 开发工具
【HarmonyOS 5】鸿蒙中@State的原理详解
@State 是 HarmonyOS ArkTS 框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动 UI 的响应式编程模式。通过将变量标记为 @State,开发者可以确保当状态值发生变化时,依赖该状态的 UI 组件会自动重新渲染,从而保持数据与界面的实时同步。 @State 是 HarmonyOS ArkTS 实现响应式编程的大基础核心,可以说整个V1和V2都是围绕它来进行组合使用。
166 0
|
4月前
|
存储 IDE 定位技术
【HarmonyOS 5】鸿蒙组件&模板服务详解 - 助力高效开发的利器
在移动应用开发领域,效率与质量始终是开发者追求的核心目标。鸿蒙系统作为新兴的操作系统,为开发者提供了丰富且强大的开发资源,其中鸿蒙组件&模板服务更是成为开发者快速构建高质量应用的得力助手。
138 0