目录

HarmonyOS鸿蒙学习笔记14ObjectLink的作用

目录

HarmonyOS鸿蒙学习笔记(14)@ObjectLink的作用

在 一文中简单介绍了@Link的作用。其局限性在于@Link是针对某个数据对象进行的整体同步,而当开发者只想针对父组件中某个数据对象的部分信息进行同步时,使用@Link就不能满足要求。如果这些部分信息是一个类对象,就可以使用@ObjectLink配合@Observed来实现。

使用 @ObjectLink 设置要求

1、 @Observed 用于类,如下面代码使用 @Observed 修饰了 ClassA 这个类。

//@Observed 用于类
@Observed
class ClassA {
  public name: string;
  public c: number;
  public id: number;

  constructor(c: number, name: string = 'OK') {
    this.name = name;
    this.c = c;
    this.id = nextID++;
  }
}

2、 @ObjectLink 用于变量。 @ObjectLink 装饰的变量类型必须为类(class type)。类要被 @Observed 装饰器所装饰,另外@ObjectLink装饰的变量是不可变的(immutable)。属性的改动是被允许的,当改动发生时,如果同一个对象被多个@ObjectLink变量所引用,那么所有拥有这些变量的自定义组件都会被通知去重新渲染。如下代码 @ObjectLink 修饰的变量a,其类型就是ClassA,而该类就被 @Observed 标注了。

//子组件ViewA 
@Component
struct ViewA {
  label: string = "ViewA1";
  //`@ObjectLink`装饰的变量类型必须为类(class type)
  @ObjectLink a: ClassA;

  build() {
    Row() {
      Button(`ViewA [${this.label}] this.a.c= ${this.a.c} +1`)
        .onClick(() => {
         //属性的改动是被允许的
          this.a.c += 1;
        })
    }.margin({ top: 10 })
  }
}

3、必须让父组件中有一个由@State、@Link、@StorageLink、@Provide或@Consume所装饰变量参与的TS表达式进行初始化。我们来看看父组件怎么写:

//父组件
@Entry
@Component
struct ViewB {
  //
  @State arrA: ClassA[] = [new ClassA(0), new ClassA(0)];

  build() {
    Column() {
      ForEach(this.arrA, (item) => {
        //将数组元素item赋值给ViewA的a属性
        ViewA({ label: `#${item.id}`, a: item })
      },
        (item) => item.id.toString()
      )
      //将数组元素item赋值给ViewA的a属性
      ViewA({ label: `ViewA this.arrA[first]`, a: this.arrA[0] })
      ViewA({ label: `ViewA this.arrA[last]`, a: this.arrA[this.arrA.length-1] })

      Button(`ViewB: reset array`)
        .margin({ top: 10 })
        .onClick(() => {
         //重新设置数组
          this.arrA = [new ClassA(0), new ClassA(0)];
        })
      Button(`ViewB: push`)
        .margin({ top: 10 })
        .onClick(() => {
          //更新数组
          this.arrA.push(new ClassA(0))
        })
      Button(`ViewB: shift`)
        .margin({ top: 10 })
        .onClick(() => {
          //删除数组的一个元素
          this.arrA.shift()
        })
    }
  }
}

运行结果如下:

https://i-blog.csdnimg.cn/blog_migrate/8d1425d3262dff09e2f425c93a477a13.png

当点击红色矩形框里的按钮任意一个,另外一个红色矩形框的按钮都跟着同步刷新。完成的运行动态图如下:

https://i-blog.csdnimg.cn/blog_migrate/1f181ff62c6837f09410d1f30d455c83.gif#pic_center

其原理总结如图:

https://i-blog.csdnimg.cn/blog_migrate/678e448d15f40aa3a2f5dc8595d30c64.png

官方资料: