1e41f4b71Sopenharmony_ci# AttributeUpdater
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Overview
4e41f4b71Sopenharmony_ciWhen dealing with frequent updates to a large number of attributes, using state variables can lead to significant computational overhead in frontend state management, requiring full updates of all attributes for individual components. Although the **AttributeModifier** mechanism allows for selective updates based on needs, the frontend still applies some default strategies for differentiation (diffing) and resetting attributes.
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ciThis is where **AttributeUpdater** comes into the picture. As a special type of **AttributeModifier**, **AttributeUpdater** not only inherits the capabilities of **AttributeModifier** but also provides the capability to obtain the attribute object. By using the attribute object, you can update specific attributes without relying on state variables. With **AttributeUpdater**, you can implement custom update strategies, further improving the performance of attribute updates. However, due to its flexibility, it does not enforce the "single source of truth" rule, and there is a risk of conflicts when the same properties are updated through both **AttributeUpdater** and state variables. You need to ensure the rationality of attribute settings to prevent conflicts.
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ci## API
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci```ts
11e41f4b71Sopenharmony_ciexport declare class AttributeUpdater<T, C = Initializer<T>> implements AttributeModifier<T> {
12e41f4b71Sopenharmony_ci  applyNormalAttribute?(instance: T): void;
13e41f4b71Sopenharmony_ci  initializeModifier(instance: T): void;
14e41f4b71Sopenharmony_ci  get attribute(): T | undefined;
15e41f4b71Sopenharmony_ci  updateConstructorParams: C;
16e41f4b71Sopenharmony_ci}
17e41f4b71Sopenharmony_ci```
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci**AttributeUpdater** implements the **AttributeModifier** API and provides additional functionality beyond the standard capabilities of **AttributeModifier**: It provides **initializeModifier** to initialize the attributes of a component, **attribute** to obtain the attribute object (which enables direct updates to the corresponding component's attributes), and **updateConstructorParams** to directly update the component's constructor parameters.
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci## Behavior Specifications
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci- You can implement the **AttributeUpdater\<T>** class and set it up through **AttributeModifier** of the component. When the binding is first established, the **initializeModifier** API is triggered to initialize attributes. The subsequent lifecycle events are consistent with those of **AttributeModifier**.
24e41f4b71Sopenharmony_ci- After the component is initialized, you can obtain the attribute object through the **attribute** method of the **AttributeUpdater** instance. If the component is not initialized, the result will be **undefined**.
25e41f4b71Sopenharmony_ci- Directly modifying attributes through **attribute** will store the latest settings within the current object and immediately trigger an update of the component's attributes.
26e41f4b71Sopenharmony_ci- Marking an instance of **AttributeUpdater** as a state variable for modification, or updating the attributes of the corresponding component through other state variables, will trigger **applyNormalAttribute**. If you do not override this logic, by default, all the attribute recorded by the **attribute** object will be updated in batch.
27e41f4b71Sopenharmony_ci- If you override the logic of **applyNormalAttribute** and do not call the **super** method, you will not be able to obtain the attribute object, and the **initializeModifier** method will not be invoked.
28e41f4b71Sopenharmony_ci- A single **AttributeUpdater** object can be associated with only one component. If it is associated with multiple components, only one component will have its attribute settings take effect.
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ci## Directly Modifying Attributes Through Modifier
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ciAfter the component is initialized, you can use the **attribute** method of the **AttributeUpdater** instance to obtain the attribute object. You can then directly modify the attributes through this attribute object, which will immediately trigger an update of the component's attributes.
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci```ts
35e41f4b71Sopenharmony_ciimport { AttributeUpdater } from '@ohos.arkui.modifier'
36e41f4b71Sopenharmony_ci
37e41f4b71Sopenharmony_ciclass MyButtonModifier extends AttributeUpdater<ButtonAttribute> {
38e41f4b71Sopenharmony_ci  initializeModifier(instance: ButtonAttribute): void {
39e41f4b71Sopenharmony_ci    instance.backgroundColor('#2787D9')
40e41f4b71Sopenharmony_ci      .width('50%')
41e41f4b71Sopenharmony_ci      .height(30)
42e41f4b71Sopenharmony_ci  }
43e41f4b71Sopenharmony_ci}
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ci@Entry
46e41f4b71Sopenharmony_ci@Component
47e41f4b71Sopenharmony_cistruct updaterDemo {
48e41f4b71Sopenharmony_ci  modifier: MyButtonModifier = new MyButtonModifier()
49e41f4b71Sopenharmony_ci
50e41f4b71Sopenharmony_ci  build() {
51e41f4b71Sopenharmony_ci    Row() {
52e41f4b71Sopenharmony_ci      Column() {
53e41f4b71Sopenharmony_ci        Button("Button")
54e41f4b71Sopenharmony_ci          .attributeModifier(this.modifier)
55e41f4b71Sopenharmony_ci          .onClick(() => {
56e41f4b71Sopenharmony_ci            this.modifier.attribute?.backgroundColor('#17A98D').width('30%')
57e41f4b71Sopenharmony_ci          })
58e41f4b71Sopenharmony_ci      }
59e41f4b71Sopenharmony_ci      .width('100%')
60e41f4b71Sopenharmony_ci    }
61e41f4b71Sopenharmony_ci    .height('100%')
62e41f4b71Sopenharmony_ci  }
63e41f4b71Sopenharmony_ci}
64e41f4b71Sopenharmony_ci```
65e41f4b71Sopenharmony_ci![AttributeUpdater](figures/AttributeUpdater.gif)
66e41f4b71Sopenharmony_ci
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ci## Updating Component Constructor Parameters Through Modifier
69e41f4b71Sopenharmony_ciYou can directly update the constructor parameters of a component using the **updateConstructorParams** method of the **AttributeUpdater** instance.
70e41f4b71Sopenharmony_ci
71e41f4b71Sopenharmony_ci```ts
72e41f4b71Sopenharmony_ciimport { AttributeUpdater } from '@ohos.arkui.modifier'
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ciclass MyTextModifier extends AttributeUpdater<TextAttribute, TextInterface> {
75e41f4b71Sopenharmony_ci  initializeModifier(instance: TextAttribute): void {
76e41f4b71Sopenharmony_ci  }
77e41f4b71Sopenharmony_ci}
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ci@Entry
80e41f4b71Sopenharmony_ci@Component
81e41f4b71Sopenharmony_cistruct updaterDemo {
82e41f4b71Sopenharmony_ci  modifier: MyTextModifier = new MyTextModifier()
83e41f4b71Sopenharmony_ci
84e41f4b71Sopenharmony_ci  build() {
85e41f4b71Sopenharmony_ci    Row() {
86e41f4b71Sopenharmony_ci      Column() {
87e41f4b71Sopenharmony_ci        Text("Text")
88e41f4b71Sopenharmony_ci          .attributeModifier(this.modifier)
89e41f4b71Sopenharmony_ci          .fontColor(Color.White)
90e41f4b71Sopenharmony_ci          .fontSize(14)
91e41f4b71Sopenharmony_ci          .border({ width: 1 })
92e41f4b71Sopenharmony_ci          .textAlign(TextAlign.Center)
93e41f4b71Sopenharmony_ci          .lineHeight(20)
94e41f4b71Sopenharmony_ci          .width(200)
95e41f4b71Sopenharmony_ci          .height(50)
96e41f4b71Sopenharmony_ci          .backgroundColor('#2787D9')
97e41f4b71Sopenharmony_ci          .onClick(() => {
98e41f4b71Sopenharmony_ci            this.modifier.updateConstructorParams('Update');
99e41f4b71Sopenharmony_ci          })
100e41f4b71Sopenharmony_ci      }
101e41f4b71Sopenharmony_ci      .width('100%')
102e41f4b71Sopenharmony_ci    }
103e41f4b71Sopenharmony_ci    .height('100%')
104e41f4b71Sopenharmony_ci  }
105e41f4b71Sopenharmony_ci}
106e41f4b71Sopenharmony_ci```
107e41f4b71Sopenharmony_ci![AttributeUpdater](figures/AttributeUpdater2.gif)
108