@Observerd和@ObjectLink的UI刷新问题 (HarmonyOS 鸿蒙Next)

@Observerd@ObjectLink的UI刷新问题 (HarmonyOS 鸿蒙Next)

Parent Class

@Observed
export class ObservedArray<T> extends Array<T> {
   constructor(...args: T[]) {
      super(...args);
   }
}

Parent and Child Classes

@Observed
class Parent {
   age: number = 0
   name: string = 'AB'
   child: ObservedArray<string> = new ObservedArray<string>('aa', 'bb', 'cc')
}

@Observed
class Child {
   age: number = 10
   name: string = 'gg'
   friends: string[] = ['aa', 'bb', 'cc']
}

State Management

@State
parent: Parent = new Parent()
@State
child: Child = new Child() // these two cannot trigger UI refresh through this.child.friends or this.parent.child

ObservedArray Usage

@State
arr: ObservedArray<string> = new ObservedArray<string>('aa', 'bb', 'cc') // this property can auto-refresh UI on push

Complete Code Example

import { ObservedArray } from '../tabs/dropdowntabs/CustomTabContents'
import { hilog } from '@kit.PerformanceAnalysisKit'
import { MixedType, MyNodeController } from '../tabs/dropdowntabs/MyNodeController'

let TAG = 'StateDemo: ->'

@Observed
class Parent {
   age: number = 0
   name: string = 'AB'
   child: ObservedArray<string> = new ObservedArray<string>('aa', 'bb', 'cc')
}

@Observed
class Child {
   age: number = 10
   name: string = 'gg'
   child: string[] = ['aa', 'bb', 'cc']
}

class Boy {
   @Track age: number = 10
   @Track name: string = 'gg'
   @Track friends: ObservedArray<string> = new ObservedArray<string>('aa', 'bb', 'cc')
}

@Builder
function testbuilder(p: MixedType) {
   Column() {
      Button('  ').onClick(() => {
         if (p instanceof Parent) {
            let pp = p as Parent
            if (pp.name == 'Cage') {
               // pp.child.push('0_0')
               pp.child = [...pp.child, '0_0']
            }
            if (pp.age == 30) {
               pp.name = 'Cage'
            }
            pp.age = 30
            hilog.info(0x0001, TAG, 'testbuilder: ' + JSON.stringify(pp))
         } else if (p instanceof Child) {
            let pp = p as Child
            if (pp.name == 'XXX') {
               pp.child.push('0o0')
            }
            if (pp.age == 18) {
               pp.name = 'XXX'
            }
            pp.age = 18
            hilog.info(0x0001, TAG, 'testbuilder2: ' + JSON.stringify(pp))
         } else if (p instanceof ObservedArray) {
            let pp = p as ObservedArray<string>
            pp.push('~_~')
            hilog.info(0x0001, TAG, 'testbuilder4: ' + JSON.stringify(pp))
         } else {
            let pp = p as Boy
            if (pp.name == 'q_p') {
               pp.friends.push('0o0')
            }
            if (pp.age == 18) {
               pp.name = 'q_p'
            }
            pp.age = 18
            hilog.info(0x0001, TAG, 'testbuilder3: ' + JSON.stringify(pp))
         }
      })
   }
}

class OuterTabContentNodeCtrl2<T extends MixedType> extends MyNodeController {
   constructor(param: T) {
      super(wrapBuilder(testbuilder), param)
   }
}

@Component
struct Test {
   [@ObjectLink](/user/ObjectLink) parent: Parent

   aboutToAppear(): void {
      hilog.info(0x0001, TAG, 'aboutToAppear: ' + JSON.stringify(this.parent))
      this.parent.age = 50
      hilog.info(0x0001, TAG, 'aboutToAppear: ' + JSON.stringify(this.parent))
      this.parent.name = 'CD'
      hilog.info(0x0001, TAG, 'aboutToAppear: ' + JSON.stringify(this.parent))
      this.parent.child.pop()
      hilog.info(0x0001, TAG, 'aboutToAppear: ' + JSON.stringify(this.parent))
      this.parent.child.push('dd', 'ee')
      hilog.info(0x0001, TAG, 'aboutToAppear: ' + JSON.stringify(this.parent))
   }

   build() {}
}

@Entry
@Component
struct StateDemo {
   @State parent: Parent = new Parent()
   @State child: Child = new Child()
   @State boy: Boy = new Boy()
   @State arr: ObservedArray<string> = new ObservedArray<string>('aa', 'bb', 'cc')

   build() {
      Column() {
         Text(JSON.stringify(this.parent)).width('100%').fontSize(16).fontColor('black')
         NodeContainer(new OuterTabContentNodeCtrl2(this.parent))
         Text(JSON.stringify(this.child)).width('100%').fontSize(16).fontColor('black')
         NodeContainer(new OuterTabContentNodeCtrl2(this.child))
         Text('' + this.boy.friends)
            .width('100%')
            .fontSize(16)
            .fontColor('black')
         NodeContainer(new OuterTabContentNodeCtrl2(this.boy))
         Text(JSON.stringify(this.arr)).width('100%').fontSize(16).fontColor('black')
         NodeContainer(new OuterTabContentNodeCtrl2(this.arr))
      }
   }
}

更多关于@Observerd和@ObjectLink的UI刷新问题 (HarmonyOS 鸿蒙Next)的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

我用的ObserverdV2做的 这个东西和link好麻烦用起来。。 费劲。

更多关于@Observerd和@ObjectLink的UI刷新问题 (HarmonyOS 鸿蒙Next)的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


看起来引用类型里面的引用类型属性监听不到,官方文档里面引用传递的类里也只有个基本类型属性

要监听到更深层的变化还得配合@ObjectLink

在HarmonyOS鸿蒙Next中,@Observerd@ObjectLink用于实现UI的自动刷新。@Observerd用于标记一个类,表示该类的实例可以被观察,当该类的属性发生变化时,会自动通知观察者。@ObjectLink用于标记一个属性,表示该属性是一个被观察对象的引用,当被引用的对象属性发生变化时,会自动刷新UI。

@Observerd标记的类需要实现IPropertyChangeListener接口,以便在属性变化时触发通知。@ObjectLink标记的属性必须引用一个被@Observerd标记的类的实例。

在UI刷新过程中,@ObjectLink会自动监听被引用对象的变化,并触发UI的重新渲染。这种机制通过鸿蒙的ArkUI框架实现,确保数据变化时UI能够及时更新,而无需手动调用刷新方法。

需要注意的是,@Observerd@ObjectLink的使用必须遵循鸿蒙的开发规范,确保数据的一致性和UI的响应性。

回到顶部