鸿蒙ACE-状态分析makeObserved

90 阅读1分钟

makeObserved接口:将非观察数据变为可观察数据

developer.huawei.com/consumer/cn…

为了将普通不可观察数据变为可观察数据,开发者可以使用makeObserved接口

转换前

/**
 *
 * MakeObservedCmp.ets
 * Created by unravel on 2024/9/10
 * @abstract
 */
import { JSON } from '@kit.ArkTS';
import { UIUtils } from '@kit.ArkUI';

class Info {
  id: number = 0;

  constructor(id: number) {
    this.id = id;
  }
}

let test: Record<string, number> = { "a": 123 };
let testJsonStr: string = JSON.stringify(test);
let test2: Record<string, Info> = { "a": new Info(20) };
let test2JsonStr: string = JSON.stringify(test2);

@ComponentV2
export struct MakeObservedCmp {
  message: Record<string, number> =
    UIUtils.makeObserved<Record<string, number>>(JSON.parse(testJsonStr) as Record<string, number>);
  message2: Record<string, Info> =
    UIUtils.makeObserved<Record<string, Info>>(JSON.parse(test2JsonStr) as Record<string, Info>);

  build() {
    Column() {
      Text(`${this.message.a}`)
        .fontSize(50)
        .onClick(() => {
          this.message.a++;
        })
      Text(`${this.message2.a.id}`)
        .fontSize(50)
        .onClick(() => {
          this.message2.a.id++;
        })
    }
    .height('100%')
    .width('100%')
  }
}

转换后

ComponentV2中转换成了如下代码

if (!("finalizeConstruction" in ViewPU.prototype)) {
    Reflect.set(ViewPU.prototype, "finalizeConstruction", () => { });
}
import JSON from "@ohos:util.json";
import { UIUtils } from "@ohos:arkui.StateManagement";
class Info {
    id: number = 0;
    constructor(id: number) {
        this.id = id;
    }
}
let test: Record<string, number> = { "a": 123 };
let testJsonStr: string = JSON.stringify(test);
let test2: Record<string, Info> = { "a": new Info(20) };
let test2JsonStr: string = JSON.stringify(test2);
export class MakeObservedCmp extends ViewV2 {
    constructor(parent, params, __localStorage, elmtId = -1, paramsLambda, extraInfo) {
        super(parent, elmtId, extraInfo);
        this.message = UIUtils.makeObserved<Record<string, number>>(JSON.parse(testJsonStr) as Record<string, number>);
        this.message2 = UIUtils.makeObserved<Record<string, Info>>(JSON.parse(test2JsonStr) as Record<string, Info>);
        this.finalizeConstruction();
    }
    message: Record<string, number>;
    message2: Record<string, Info>;
    initialRender() {
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Column.create();
            Column.height('100%');
            Column.width('100%');
        }, Column);
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Text.create(`${this.message.a}`);
            Text.fontSize(50);
            Text.onClick(() => {
                this.message.a++;
            });
        }, Text);
        Text.pop();
        this.observeComponentCreation2((elmtId, isInitialRender) => {
            Text.create(`${this.message2.a.id}`);
            Text.fontSize(50);
            Text.onClick(() => {
                this.message2.a.id++;
            });
        }, Text);
        Text.pop();
        Column.pop();
    }
    rerender() {
        this.updateDirtyElements();
    }
}

如果是ComponentV1,会转换成如下代码

image.png

UIUtil.makeObserved

可以看到编译过后,UIUtils.makeObserved没有任何改变

我们可以从 gitee.com/openharmony… 中看到这个方法的具体实现

最终实际调用了RefInfo的get方法

image.png

RefInfo.get

image.png

小结

  1. 调用makeObserved会根据传入的对象是否已经是被观察的对象,做不同的处理
  2. 根据传入target的类型分别创建不同类型的代理处理对象