HarmonyOS 鸿蒙Next @Observed & @ObjectLink装饰器-嵌套类对象属性变化更新UI

发布于 1周前 作者 yuanlaile 最后一次编辑是 5天前 来自 鸿蒙OS

HarmonyOS 鸿蒙Next @Observed & @ObjectLink装饰器-嵌套类对象属性变化更新UI

在实际应用开发中,应用会根据开发需要,封装自己的数据模型。对于多层嵌套的情况,比如二维数组,或者数组项class,或者class的属性是class,他们的第二层的属性变化是无法观察到的,当这些class的第二层属性变化时无法触发UI刷新,此时我们可以使用@Observed/@ObjectLink装饰器来实现class的第二层属性变化触发UI刷新。

@ObjectLink@Observed类装饰器用于在涉及嵌套对象或数组的场景中进行双向数据同步:

  1. @Observed装饰的类,可以被观察到属性的变化。创建类时需要使用new的方式传递数据,不能使用值传递。
  2. 子组件中@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定。@ObjectLink不能用于entry标识的组件内。
  3. 单独使用@Observed是没有任何作用的,需要搭配@ObjectLink或者@Prop使用。

如下示例中,想要修改Person数组中的每个数据引起UI变化,需要引入多种状态数据,比较麻烦:

import promptAction from '@ohos.promptAction';
class Person{
  id:number;
  name:string;
  age:number;

  constructor(id:number,name:string,age:number) {
    this.id = id
    this.name=name
    this.age=age
  }
}

@Entry
@Component
struct ObservedTest {

  @State
  personList:Person[] = [
    new Person(1,'zs',10),
    new Person(2,'ls',11),
    new Person(3,'ww',12),
  ]

  build(){
    Column(){
      ForEach(this.personList,(item:Person,index:number)=>{
        CompB({person:item,personList:$personList,index:index})
      })
    }
  }
}

@Component
struct CompB {

  person:Person

  @Link
  personList:Person[]

  index:number

  build() {
    Column(){
      Text(`当前person信息为:${this.person.id}-${this.person.name}-${this.person.age}`)
        .width('100%')

      Button("修改person中的age")
        .onClick(()=>{
          const newAge = this.person.age +=1
          this.personList[this.index] = new Person(this.person.id,this.person.name,newAge)
          promptAction.showToast({message: this.person.age.toString()})
        })
    }
  }
}

预览图

cke_24063.png

可以直接使用[@Observed](/user/Observed)装饰器装饰Person类,[@ObjectLink](/user/ObjectLink)装饰组件中的Person对象,这样就可以做到当组件中的person对象改变时当前Person对象变化被监听,从而引起UI刷新。代码如下:

import promptAction from '@ohos.promptAction';
[@Observed](/user/Observed)
class Person{
  id:number;
  name:string;
  age:number;

  constructor(id:number,name:string,age:number) {
    this.id = id
    this.name=name
    this.age=age
  }
}

@Entry
@Component
struct ObservedTest {

  @State
  personList:Person[] = [
   new Person(1,'zs',10),
   new Person(2,'ls',11),
   new Person(3,'ww',12),
  ]

  build(){
    Column(){
      ForEach(this.personList,(item:Person,index:number)=>{
        CompB({person:item})
      })
    }
  }



}

@Component
struct CompB {
  [@ObjectLink](/user/ObjectLink)
  person:Person

  build() {
    Column(){
      Text(`当前person信息为:${this.person.id}-${this.person.name}-${this.person.age}`)
        .width('100%')

      Button("修改person中的age")
        .onClick(()=>{
          this.person.age +=1
          promptAction.showToast({message: this.person.age.toString()})
        })
    }
  }
}

预览如下:

cke_44201.png

当点击按钮改变person对象中的属性时,会引起UI刷新。

2 回复
学习了

在HarmonyOS开发中,@Observed@ObjectLink 装饰器用于实现数据绑定和响应式编程,使得当数据模型发生变化时,UI界面能够自动更新。

对于嵌套类对象属性的变化更新UI,需要注意以下几点:

  1. 确保嵌套对象也被观察:如果嵌套对象本身也有属性需要被观察,那么这个嵌套对象本身也应该使用@Observed装饰器进行标注。

  2. 正确设置属性访问器:在嵌套类中,确保属性的getter和setter方法被正确设置,以便系统能够检测到属性的变化。

  3. 使用@ObjectLink进行绑定:在UI组件中,通过@ObjectLink装饰器将UI组件的属性与数据模型中的嵌套对象属性进行绑定。

  4. 确保数据模型更新:当嵌套对象的属性发生变化时,确保这个变化能够触发数据模型的更新,从而进一步触发UI的更新。

  5. 注意作用域和生命周期:确保嵌套对象和上层对象在组件的生命周期内始终有效,避免因为作用域或生命周期问题导致数据绑定失效。

如果以上方法都正确无误,但问题依旧没法解决,请联系官网客服。官网地址是:https://www.itying.com/category-93-b0.html。

回到顶部