• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Updating Widget Content Through the router or call Event
2
3
4On the widget page, the **postCardAction** API can be used to trigger a router or call event to start a UIAbility, which then updates the widget content. The following is an example of this widget update mode.
5
6> **NOTE**
7>
8> This topic describes development for dynamic widgets. For static widgets, see [FormLink](../reference/arkui-ts/ts-container-formlink.md).
9
10## Updating Widget Content Through the router Event
11
12- On the widget page, register the **onClick** event callback of the button and call the **postCardAction** API in the callback to trigger the router event to start the UIAbility.
13
14  ```ts
15  let storage = new LocalStorage();
16  @Entry(storage)
17  @Component
18  struct WidgetCard {
19    @LocalStorageProp('detail') detail: string = 'init';
20
21    build() {
22      Column() {
23        Button ('Redirect')
24          .margin('20%')
25          .onClick(() => {
26            console.info('postCardAction to EntryAbility');
27            postCardAction(this, {
28              'action': 'router',
29              'abilityName': 'EntryAbility', // Only the UIAbility of the current application is allowed.
30              'params': {
31                'detail': 'RouterFromCard'
32              }
33            });
34          })
35        Text(`${this.detail}`).margin('20%')
36      }
37      .width('100%')
38      .height('100%')
39    }
40  }
41  ```
42
43- In the **onCreate()** or **onNewWant()** lifecycle callback of the UIAbility, use the input parameter **want** to obtain the ID (**formID**) and other information of the widget, and then call the [updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform) API to update the widget.
44
45  ```ts
46  import UIAbility from '@ohos.app.ability.UIAbility';
47  import formBindingData from '@ohos.app.form.formBindingData';
48  import formProvider from '@ohos.app.form.formProvider';
49  import formInfo from '@ohos.app.form.formInfo';
50  import AbilityConstant from '@ohos.app.ability.AbilityConstant';
51  import Want from '@ohos.app.ability.Want';
52  import Base from '@ohos.base'
53
54  export default class EntryAbility extends UIAbility {
55    // If the UIAbility is started for the first time, onCreate is triggered after the router event is received.
56    onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
57      this.handleFormRouterEvent(want);
58    }
59
60    handleFormRouterEvent(want: Want) {
61      console.info('Want:' + JSON.stringify(want));
62      if (want.parameters && want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) {
63        let curFormId = JSON.stringify(want.parameters[formInfo.FormParam.IDENTITY_KEY]);
64        let message: string = JSON.parse(JSON.stringify(want.parameters.params)).detail;
65        console.info(`UpdateForm formId: ${curFormId}, message: ${message}`);
66        let formData: Record<string, string> = {
67          "detail": message + ': UIAbility.', // It matches the widget layout.
68        };
69        let formMsg = formBindingData.createFormBindingData(formData)
70        formProvider.updateForm(curFormId, formMsg).then((data) => {
71          console.info('updateForm success.' + JSON.stringify(data));
72        }).catch((error: Base.BusinessError) => {
73          console.error('updateForm failed:' + JSON.stringify(error));
74        })
75      }
76    }
77    // If the UIAbility is running in the background, onNewWant is triggered after the router event is received.
78    onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam) {
79      console.info('onNewWant Want:' + JSON.stringify(want));
80      if (want.parameters && want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) {
81        let curFormId = JSON.stringify(want.parameters[formInfo.FormParam.IDENTITY_KEY]);
82        let message: string = JSON.parse(JSON.stringify(want.parameters.params)).detail;
83        console.info(`UpdateForm formId: ${curFormId}, message: ${message}`);
84        let formData: Record<string, string> = {
85          "detail": message +': onNewWant UIAbility.', // Matches the widget layout.
86        };
87        let formMsg = formBindingData.createFormBindingData(formData)
88        formProvider.updateForm(curFormId, formMsg).then((data) => {
89          console.info('updateForm success.' + JSON.stringify(data));
90        }).catch((error: Base.BusinessError) => {
91          console.error('updateForm failed:' + JSON.stringify(error));
92        })
93      }
94    }
95
96    ...
97  }
98  ```
99
100## Updating Widget Content Through the call Event
101
102- When using the call event of the **postCardAction** API, the value of **formId** must be updated in the **onAddForm** callback of the FormExtensionAbility.
103
104   ```ts
105   import formBindingData from '@ohos.app.form.formBindingData';
106   import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
107   import Want from '@ohos.app.ability.Want';
108
109   export default class EntryFormAbility extends FormExtensionAbility {
110    onAddForm(want: Want) {
111      let dataObj1 = new Map<string, string>();
112      if (want.parameters && want.parameters["ohos.extra.param.key.form_identity"] != undefined) {
113        let formId: string = JSON.parse(JSON.stringify(want.parameters["ohos.extra.param.key.form_identity"]));
114        dataObj1.set("formId", formId);
115      }
116      let obj1 = formBindingData.createFormBindingData(dataObj1);
117      return obj1;
118    }
119    ...
120   };
121   ```
122
123- On the widget page, register the **onClick** event callback of the button and call the **postCardAction** API in the callback to trigger the call event to start the UIAbility.
124
125  ```ts
126  let storage = new LocalStorage();
127  @Entry(storage)
128  @Component
129  struct WidgetCard {
130    @LocalStorageProp('detail') detail: string = 'init';
131    @LocalStorageProp('formId') formId: string = '0';
132
133    build() {
134      Column() {
135        Button ('Start in Background')
136          .margin('20%')
137          .onClick(() => {
138            console.info('postCardAction to EntryAbility');
139            postCardAction(this, {
140              'action': 'call',
141              'abilityName': 'EntryAbility', // Only the UIAbility of the current application is allowed.
142              'params': {
143                'method': 'funA',
144                'formId': this.formId,
145                'detail': 'CallFromCard'
146              }
147            });
148          })
149        Text(`${this.detail}`).margin('20%')
150      }
151      .width('100%')
152      .height('100%')
153    }
154  }
155  ```
156
157- Listen for the method required by the call event in the **onCreate** callback of the UIAbility, and then call the [updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform) API in the corresponding method to update the widget.
158
159  ```ts
160  import UIAbility from '@ohos.app.ability.UIAbility';
161  import formBindingData from '@ohos.app.form.formBindingData';
162  import formProvider from '@ohos.app.form.formProvider';
163  import Want from '@ohos.app.ability.Want';
164  import Base from '@ohos.base'
165  import rpc from '@ohos.rpc';
166  import AbilityConstant from '@ohos.app.ability.AbilityConstant';
167
168  const MSG_SEND_METHOD: string = 'funA';
169
170  class MyParcelable implements rpc.Parcelable {
171    num: number;
172    str: string;
173    constructor(num: number, str: string) {
174      this.num = num;
175      this.str = str;
176    }
177    marshalling(messageSequence: rpc.MessageSequence): boolean {
178      messageSequence.writeInt(this.num);
179      messageSequence.writeString(this.str);
180      return true;
181    }
182    unmarshalling(messageSequence: rpc.MessageSequence): boolean {
183      this.num = messageSequence.readInt();
184      this.str = messageSequence.readString();
185      return true;
186    }
187  }
188
189  // After the call event is received, the method listened for by the callee is triggered.
190  let FunACall = (data: rpc.MessageSequence) => {
191    // Obtain all parameters transferred in the call event.
192    let params: Record<string, string> = JSON.parse(data.readString())
193    if (params.formId !== undefined) {
194      let curFormId: string = params.formId;
195      let message: string = params.detail;
196      console.info(`UpdateForm formId: ${curFormId}, message: ${message}`);
197      let formData: Record<string, string> = {
198        "detail": message
199      };
200      let formMsg: formBindingData.FormBindingData = formBindingData.createFormBindingData(formData);
201      formProvider.updateForm(curFormId, formMsg).then((data) => {
202        console.info('updateForm success.' + JSON.stringify(data));
203      }).catch((error: Base.BusinessError) => {
204        console.error('updateForm failed:' + JSON.stringify(error));
205      })
206    }
207    return new MyParcelable(1, 'aaa');
208  }
209
210  export default class EntryAbility extends UIAbility {
211    // If the UIAbility is started for the first time, onCreate is triggered after the call event is received.
212    onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
213      console.info('Want:' + JSON.stringify(want));
214      try {
215        // Listen for the method required by the call event.
216        this.callee.on(MSG_SEND_METHOD, FunACall);
217      } catch (error) {
218        console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error as Base.BusinessError)}`)
219      }
220    }
221  }
222  ```
223