DEV Community

HarmonyOS
HarmonyOS

Posted on

How to obtain the original data corresponding to the data observed by @ObservedV2?

Read the original article:How to obtain the original data corresponding to the data observed by @ObservedV2?

How to obtain the original data corresponding to the data observed by @ObservedV2?

Problem Description

In an object decorated with @ObservedV2, the member variable names decorated with @Trace are prefixed with __ob_. How can the original object be obtained?

Background Knowledge

The V2 state management decorator generates getter and setter methods for the decorated variable and adds the__ob_ prefix to the original variable name. For performance reasons the getTarget interface does not process the prefix generated by the V2 decorator. Therefore, when passing an instance of a class object decorated with @ObservedV2 to the getTarget interface , the returned object is still the object itself, and the property names decorated with @Trace still have the__ob_ prefix.

Solution

You can initialize a state management object V1 with the same structure using the @Observed and @ObjectLink decorators, and then use the getTarget interface to retrieve the original data of the V1 object. The retrieved data will have the same structure as the original V2 object. The detailed steps are as follows:

1.Define V1 and V2 objects with the same structure:

   @ObservedV2
   class FormDataClassV2 {
     @Trace name: string = '';
     @Trace price: number = 0;
   }

   @Observed
   class FormDataClassV1 {
     @Track name: string = '';
     @Track price: number = 0;

     constructor(v: FormDataClassV2) {
       this.name = v.name;
       this.price = v.price;
     }
   }
Enter fullscreen mode Exit fullscreen mode

2.Initialize the V1 object using the V2 object:

   let dataV1: FormDataClassV1 = new FormDataClassV1(this.dataV2);
Enter fullscreen mode Exit fullscreen mode

3.Use the getTarget interface to retrieve the raw data:

   let rawV1 = UIUtils.getTarget(dataV1);
Enter fullscreen mode Exit fullscreen mode

The complete demo is as follows:

import { UIUtils } from '@kit.ArkUI';

@ObservedV2
class FormDataClassV2 {
  @Trace name: string = '';
  @Trace price: number = 0;
}

@Observed
class FormDataClassV1 {
  @Track name: string = '';
  @Track price: number = 0;

  constructor(v: FormDataClassV2) {
    this.name = v.name;
    this.price = v.price;
  }
}

@Entry
@ComponentV2
struct FormDataClassPage {
  @Local message: string = 'Hello World';
  @Local dataV2: FormDataClassV2 = new FormDataClassV2();

  build() {
    RelativeContainer() {
      Text(this.message)
        .id('HelloWorld')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .onClick(() => {
          let dataV1: FormDataClassV1 = new FormDataClassV1(this.dataV2); // Initialize a V1 object with a V2 object
          let rawV1 = UIUtils.getTarget(dataV1); // Use the getTarget interface to obtain the original object
          console.info(JSON.stringify(rawV1)); // In this case, the printed logs do not contain the __ob_ framework
        })
    }
    .height('100%')
    .width('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

Q: What are the use cases for the getTarget interface?
A: getTarget can retrieve the original object of the proxy object and modify its data without triggering a UI refresh.
Use cases include:

  • In type comparison or serialization scenarios, it is necessary to obtain the original object.
  • In third-party library integration scenarios, it is necessary to transmit the original object data.
  • In scenarios involving extensive data modifications, such as data sorting, operations on the original object can avoid the performance overhead of the proxy layer.

Verification Result

output1.png

This example supports API Version 20 Release and above.
This example supports HarmonyOS 6.0.0 Release SDK and above.
This example requires DevEco Studio 6.0.0 Release and above to compile and run.

Written by Emine Inan

Top comments (0)