• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# AttributeUpdater
2
3## 概述
4大量属性频繁更新时,如果使用状态变量,会导致前端状态管理计算量太大,并需要对单个组件进行全量的属性更新。虽然可以通过[AttributeModifier](../reference/apis-arkui/arkui-ts/ts-universal-attributes-attribute-modifier.md)的机制按需更新,但是前端还是默认会有一些diff和reset的策略。
5
6为此引入了`AttributeUpdater`的能力,它是一个特殊的`AttributeModifier`,除了继承`AttributeModifier`的能力,还提供了获取属性对象的能力。通过属性对象可以不经过状态变量,直接更新对应属性。使用`AttributeUpdater`,开发者可实现自定义的更新策略,进一步提高属性更新的性能。但是由于该能力比较灵活,无法限制“单一数据源”的规则,同时和状态变量更新相同属性时,存在相互覆盖的情况,需要开发者自己保障属性设置的合理性。
7
8## 接口定义
9
10```ts
11export declare class AttributeUpdater<T, C = Initializer<T>> implements AttributeModifier<T> {
12  applyNormalAttribute?(instance: T): void;
13  initializeModifier(instance: T): void;
14  get attribute(): T | undefined;
15  updateConstructorParams: C;
16}
17```
18
19`AttributeUpdater`实现了`AttributeModifier`接口,额外提供了`initializeModifier`,可以对组件的属性进行初始化,并且通过`attribute`属性方法,获取到属性对象,通过该对象直接更新对应组件的属性。另外也可以直接通过updateConstructorParams更新组件的构造参数。
20
21## 行为规格
22
23- 开发者可以实现一个`AttributeUpdater<T>`的类,并通过组件的`AttributeModifier`设置,首次绑定时会触发`initializeModifier`方法,进行属性的初始化,后续其它的生命周期和`AttributeModifier`保持一致。
24- 组件初始化完成之后,可以通过`AttributeUpdater`实例的`attribute`属性方法,获取到属性对象,否则为undefined。
25- 通过`attribute`属性对象直接修改属性,会将最新设置的属性记录在当前对象中,并立即触发组件属性的更新。
26- 如果将`AttributeUpdater`实例标记为状态变量进行修改,或者通过其它状态变量更新对应组件的属性,会触发`applyNormalAttribute`的流程,如果开发者没有覆写该逻辑,默认会将属性对象记录的所有属性,批量进行一次更新。
27- 如果开发者复写`applyNormalAttribute`的逻辑,并且不调用super的该方法,将会失去获取`attribute`属性对象的能力,不会调用`initializeModifier`方法。
28- 一个`AttributeUpdater`对象只能同时关联一个组件,否则只会有一个组件生效属性设置。
29
30## 通过modifier直接修改属性
31
32组件初始化完成之后,可以通过`AttributeUpdater`实例的`attribute`属性方法,获取到属性对象,通过属性对象直接修改属性,会立即触发组件属性的更新。
33
34```ts
35import { AttributeUpdater } from '@ohos.arkui.modifier'
36
37class MyButtonModifier extends AttributeUpdater<ButtonAttribute> {
38  initializeModifier(instance: ButtonAttribute): void {
39    instance.backgroundColor('#2787D9')
40      .width('50%')
41      .height(30)
42  }
43}
44
45@Entry
46@Component
47struct updaterDemo {
48  modifier: MyButtonModifier = new MyButtonModifier()
49
50  build() {
51    Row() {
52      Column() {
53        Button("Button")
54          .attributeModifier(this.modifier)
55          .onClick(() => {
56            this.modifier.attribute?.backgroundColor('#17A98D').width('30%')
57          })
58      }
59      .width('100%')
60    }
61    .height('100%')
62  }
63}
64```
65![AttributeUpdater](figures/AttributeUpdater.gif)
66
67
68## 通过modifier更新组件的构造参数
69可以直接通过`AttributeUpdater`实例的updateConstructorParams方法,更新组件的构造参数。
70
71```ts
72import { AttributeUpdater } from '@ohos.arkui.modifier'
73
74class MyTextModifier extends AttributeUpdater<TextAttribute, TextInterface> {
75  initializeModifier(instance: TextAttribute): void {
76  }
77}
78
79@Entry
80@Component
81struct updaterDemo {
82  modifier: MyTextModifier = new MyTextModifier()
83
84  build() {
85    Row() {
86      Column() {
87        Text("Text")
88          .attributeModifier(this.modifier)
89          .fontColor(Color.White)
90          .fontSize(14)
91          .border({ width: 1 })
92          .textAlign(TextAlign.Center)
93          .lineHeight(20)
94          .width(200)
95          .height(50)
96          .backgroundColor('#2787D9')
97          .onClick(() => {
98            this.modifier.updateConstructorParams('Update');
99          })
100      }
101      .width('100%')
102    }
103    .height('100%')
104  }
105}
106```
107![AttributeUpdater](figures/AttributeUpdater2.gif)