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