1# JS卡片开发指导(Stage模型) 2<!--Kit: Form Kit--> 3<!--Subsystem: Ability--> 4<!--Owner: @cx983299475--> 5<!--Designer: @xueyulong--> 6<!--Tester: @chenmingze--> 7<!--Adviser: @Brilliantry_Rui--> 8Stage模型是从API 9开始支持,目前主推且会长期演进的模型。该模型采用面向对象的方式,将应用组件以类接口的形式开放给开发者,可以进行派生,利于扩展能力。 9 10## 接口说明 11 12FormExtensionAbility类拥有如下API接口,具体的API介绍详见[接口文档](../reference/apis-form-kit/js-apis-app-form-formExtensionAbility.md)。 13 14| 接口名 | 描述 | 15| -------- | -------- | 16| onAddForm(want: Want): formBindingData.FormBindingData | 卡片提供方接收创建卡片的通知接口。 | 17| onCastToNormalForm(formId: string): void | 卡片提供方接收临时卡片转常态卡片的通知接口。 | 18| onUpdateForm(formId: string): void | 卡片提供方接收更新卡片的通知接口。 | 19| onChangeFormVisibility(newStatus: Record<string, number>): void | 卡片提供方接收修改可见性的通知接口。 | 20| onFormEvent(formId: string, message: string): void | 卡片提供方接收处理卡片事件的通知接口。 | 21| onRemoveForm(formId: string): void | 卡片提供方接收销毁卡片的通知接口。 | 22| onConfigurationUpdate(newConfig: Configuration): void | 当系统配置更新时调用。 | 23 24formProvider类部分API接口如下,具体的API介绍详见[接口文档](../reference/apis-form-kit/js-apis-app-form-formProvider.md)。 25 26| 接口名 | 描述 | 27| -------- | -------- | 28| setFormNextRefreshTime(formId: string, minute: number, callback: AsyncCallback<void>): void | 设置指定卡片的下一次更新时间。 | 29| setFormNextRefreshTime(formId: string, minute: number): Promise<void> | 设置指定卡片的下一次更新时间,以promise方式返回。 | 30| updateForm(formId: string, formBindingData: formBindingData.FormBindingData, callback: AsyncCallback<void>): void | 更新指定的卡片。 | 31| updateForm(formId: string, formBindingData: formBindingData.FormBindingData): Promise<void> | 更新指定的卡片,以promise方式返回。 | 32 33formBindingData类部分API接口如下,具体的API介绍详见[接口文档](../reference/apis-form-kit/js-apis-app-form-formBindingData.md)。 34 35| 接口名 | 描述 | 36| -------- | -------- | 37| createFormBindingData(obj?: Object \| string): FormBindingData | 创建一个FormBindingData对象。 | 38 39 40## 开发步骤 41 42Stage卡片开发,即基于[Stage模型](../application-models/stage-model-development-overview.md)的卡片提供方开发,主要涉及如下关键步骤: 43 44- [创建卡片FormExtensionAbility](#创建卡片formextensionability):卡片生命周期回调函数FormExtensionAbility开发。 45 46- [配置卡片配置文件](#配置卡片配置文件):配置应用配置文件module.json5和profile配置文件。 47 48- [卡片信息的持久化](#卡片信息的持久化):对卡片信息进行持久化管理。 49 50- [卡片数据交互](#卡片数据交互):通过updateForm更新卡片显示的信息。 51 52- [开发卡片页面](#开发卡片页面):使用HML+CSS+JSON开发JS卡片页面。 53 54- [开发卡片事件](#开发卡片事件):为卡片添加router事件和message事件。 55 56 57### 创建卡片FormExtensionAbility 58 59创建Stage模型的卡片,需实现FormExtensionAbility生命周期接口。先参考<!--RP1-->[DevEco Studio服务卡片开发指南](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-service-widget-V5)<!--RP1End-->生成服务卡片模板。 60 611. 在EntryFormAbility.ets中,导入相关模块。 62 ```ts 63 import { Want } from '@kit.AbilityKit'; 64 import { formBindingData, FormExtensionAbility, formInfo, formProvider } from '@kit.FormKit'; 65 import { hilog } from '@kit.PerformanceAnalysisKit'; 66 import { BusinessError } from '@kit.BasicServicesKit'; 67 68 const TAG: string = 'JsCardFormAbility'; 69 const DOMAIN_NUMBER: number = 0xFF00; 70 ``` 71 722. 在EntryFormAbility.ets中,实现FormExtension生命周期接口。 73 74 ```ts 75 export default class EntryFormAbility extends FormExtensionAbility { 76 onAddForm(want: Want): formBindingData.FormBindingData { 77 hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onAddForm'); 78 // 使用方创建卡片时触发,提供方需要返回卡片数据绑定类 79 let obj: Record<string, string> = { 80 'title': 'titleOnCreate', 81 'detail': 'detailOnCreate' 82 }; 83 let formData: formBindingData.FormBindingData = formBindingData.createFormBindingData(obj); 84 return formData; 85 } 86 onCastToNormalForm(formId: string): void { 87 // 使用方将临时卡片转换为常态卡片触发,提供方需要做相应的处理,当前卡片使用方不存在临时卡片场景 88 hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onCastToNormalForm'); 89 } 90 onUpdateForm(formId: string): void { 91 // 若卡片支持定时更新/定点更新/卡片使用方主动请求更新功能,则提供方需要重写该方法以支持数据更新 92 hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onUpdateForm'); 93 let obj: Record<string, string> = { 94 'title': 'titleOnUpdate', 95 'detail': 'detailOnUpdate' 96 }; 97 let formData: formBindingData.FormBindingData = formBindingData.createFormBindingData(obj); 98 formProvider.updateForm(formId, formData).catch((error: BusinessError) => { 99 hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] updateForm, error:' + JSON.stringify(error)); 100 }); 101 } 102 onChangeFormVisibility(newStatus: Record<string, number>): void { 103 // 使用方发起可见或者不可见通知触发,提供方需要做相应的处理,仅系统应用生效 104 hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onChangeFormVisibility'); 105 //... 106 } 107 onFormEvent(formId: string, message: string): void { 108 // 若卡片支持触发事件,则需要重写该方法并实现对事件的触发 109 hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onFormEvent'); 110 } 111 onRemoveForm(formId: string): void { 112 // 删除卡片实例数据 113 hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onRemoveForm'); 114 //... 115 } 116 onAcquireFormState(want: Want): formInfo.FormState { 117 return formInfo.FormState.READY; 118 } 119 } 120 ``` 121 122> **说明:** 123> FormExtensionAbility不能常驻后台,即在卡片生命周期回调函数中无法处理长时间的任务。 124 125 126### 配置卡片配置文件 127 1281. 卡片需要在[module.json5配置文件](../quick-start/module-configuration-file.md)中的extensionAbilities标签下,配置ExtensionAbility相关信息。FormExtensionAbility需要填写metadata元信息标签,其中键名称为固定字符串"ohos.extension.form",资源为卡片的具体配置信息的索引。 129 配置示例如下: 130 131 132 ```json 133 { 134 "module": { 135 // ... 136 "extensionAbilities": [ 137 { 138 "name": "JsCardFormAbility", 139 "srcEntry": "./ets/jscardformability/JsCardFormAbility.ts", 140 "description": "$string:JSCardFormAbility_desc", 141 "label": "$string:JSCardFormAbility_label", 142 "type": "form", 143 "metadata": [ 144 { 145 "name": "ohos.extension.form", 146 "resource": "$profile:form_jscard_config" 147 } 148 ] 149 } 150 ] 151 } 152 } 153 ``` 154 1552. 卡片的具体配置信息。在上述FormExtensionAbility的元信息("metadata"配置项)中,可以指定卡片具体配置信息的资源索引。例如当resource指定为$profile:form_config时,会使用开发视图的resources/base/profile/目录下的form_config.json作为卡片profile配置文件。内部字段结构说明如下表所示。 156 157 **表1** 卡片profile配置文件 158 159 | 属性名称 | 含义 | 数据类型 | 是否可缺省 | 160 | -------- | -------- | -------- | -------- | 161 | name | 表示卡片的类名,字符串最大长度为127字节。 | 字符串 | 否 | 162 | description | 表示卡片的描述。取值可以是描述性内容,也可以是对描述性内容的资源索引,以支持多语言。字符串最大长度为255字节。 | 字符串 | 可缺省,缺省为空。 | 163 | src | 表示卡片对应的UI代码的完整路径。 | 字符串 | 否 | 164 | window | 用于定义与显示窗口相关的配置。 | 对象 | 可缺省。 | 165 | isDefault | 表示该卡片是否为默认卡片,每个UIAbility有且只有一个默认卡片。<br/>- true:默认卡片。<br/>- false:非默认卡片。 | 布尔值 | 否 | 166 | colorMode | 表示卡片的主题样式,取值范围如下:<br/>- auto:自适应。<br/>- dark:深色主题。<br/>- light:浅色主题。 | 字符串 | 可缺省,缺省值为“auto”。 | 167 | supportDimensions | 表示卡片支持的外观规格,取值范围:<br/>- 1 \* 2:表示1行2列的二宫格。<br/>- 2 \* 2:表示2行2列的四宫格。<br/>- 2 \* 4:表示2行4列的八宫格。<br/>- 4 \* 4:表示4行4列的十六宫格。 | 字符串数组 | 否 | 168 | defaultDimension | 表示卡片的默认外观规格,取值必须在该卡片supportDimensions配置的列表中。 | 字符串 | 否 | 169 | updateEnabled | 表示卡片是否支持周期性刷新,取值范围:<br/>- true:表示支持周期性刷新,可以在定时刷新(updateDuration)和定点刷新(scheduledUpdateTime)两种方式任选其一,优先选择定时刷新。<br/>- false:表示不支持周期性刷新。 | 布尔类型 | 否 | 170 | scheduledUpdateTime | 表示卡片的定点刷新的时刻,采用24小时制,精确到分钟。<br/>updateDuration参数优先级高于scheduledUpdateTime,两者同时配置时,以updateDuration配置的刷新时间为准。 | 字符串 | 可缺省,缺省值为“0:0”。 | 171 | updateDuration | 表示卡片定时刷新的更新周期,单位为30分钟,取值为自然数。<br/>当取值为0时,表示该参数不生效。<br/>当取值为正整数N时,表示刷新周期为30\*N分钟。<br/>updateDuration参数优先级高于scheduledUpdateTime,两者同时配置时,以updateDuration配置的刷新时间为准。 | 数值 | 可缺省,缺省值为“0”。 | 172 | formConfigAbility | 表示卡片的配置跳转链接,采用URI格式。 | 字符串 | 可缺省,缺省值为空。 | 173 | formVisibleNotify | 标识是否允许卡片使用卡片可见性通知。 | 字符串 | 可缺省,缺省值为空。 | 174 | metaData | 表示卡片的自定义信息,包含customizeData数组标签。 | 对象 | 可缺省,缺省值为空。 | 175 176 配置示例如下: 177 178 179 ```json 180 { 181 "forms": [ 182 { 183 "name": "WidgetJS", 184 "description": "$string:JSCardEntryAbility_desc", 185 "src": "./js/WidgetJS/pages/index/index", 186 "window": { 187 "designWidth": 720, 188 "autoDesignWidth": true 189 }, 190 "colorMode": "auto", 191 "isDefault": true, 192 "updateEnabled": true, 193 "scheduledUpdateTime": "10:30", 194 "updateDuration": 1, 195 "defaultDimension": "2*2", 196 "supportDimensions": [ 197 "2*2" 198 ] 199 } 200 ] 201 } 202 ``` 203 204 205### 卡片信息的持久化 206 207因大部分卡片提供方都不是常驻服务,只有在需要使用时才会被拉起获取卡片信息,且卡片管理服务支持对卡片进行多实例管理,卡片ID对应实例ID,因此若卡片提供方支持对卡片数据进行配置,则需要对卡片的业务数据按照卡片ID进行持久化管理,以便在后续获取、更新以及拉起时能获取到正确的卡片业务数据。 208 209 210```ts 211import { common, Want } from '@kit.AbilityKit'; 212import { hilog } from '@kit.PerformanceAnalysisKit'; 213import { formBindingData, FormExtensionAbility } from '@kit.FormKit'; 214import { BusinessError } from '@kit.BasicServicesKit'; 215import { preferences } from '@kit.ArkData'; 216 217const TAG: string = 'JsCardFormAbility'; 218const DATA_STORAGE_PATH: string = '/data/storage/el2/base/haps/form_store'; 219const DOMAIN_NUMBER: number = 0xFF00; 220 221let storeFormInfo = async (formId: string, formName: string, tempFlag: boolean, context: common.FormExtensionContext): Promise<void> => { 222 // 此处仅对卡片ID:formId,卡片名:formName和是否为临时卡片:tempFlag进行了持久化 223 let formInfo: Record<string, string | boolean | number> = { 224 'formName': formName, 225 'tempFlag': tempFlag, 226 'updateCount': 0 227 }; 228 try { 229 const storage: preferences.Preferences = await preferences.getPreferences(context, DATA_STORAGE_PATH); 230 // put form info 231 await storage.put(formId, JSON.stringify(formInfo)); 232 hilog.info(DOMAIN_NUMBER, TAG, `[EntryFormAbility] storeFormInfo, put form info successfully, formId: ${formId}`); 233 await storage.flush(); 234 } catch (err) { 235 hilog.error(DOMAIN_NUMBER, TAG, `[EntryFormAbility] failed to storeFormInfo, err: ${JSON.stringify(err as BusinessError)}`); 236 } 237} 238 239export default class JsCardFormAbility extends FormExtensionAbility { 240 onAddForm(want: Want): formBindingData.FormBindingData { 241 hilog.info(DOMAIN_NUMBER, TAG, '[JsCardFormAbility] onAddForm'); 242 243 if (want.parameters) { 244 let formId = JSON.stringify(want.parameters['ohos.extra.param.key.form_identity']); 245 let formName = JSON.stringify(want.parameters['ohos.extra.param.key.form_name']); 246 let tempFlag = want.parameters['ohos.extra.param.key.form_temporary'] as boolean; 247 // 将创建的卡片信息持久化,以便在下次获取/更新该卡片实例时进行使用 248 // 此接口请根据实际情况实现,具体请参考:FormExtAbility Stage模型卡片实例 249 storeFormInfo(formId, formName, tempFlag, this.context); 250 } 251 252 let obj: Record<string, string> = { 253 'title': 'titleOnCreate', 254 'detail': 'detailOnCreate' 255 }; 256 let formData: formBindingData.FormBindingData = formBindingData.createFormBindingData(obj); 257 return formData; 258 } 259} 260``` 261 262且需要适配onRemoveForm卡片删除通知接口,在其中实现卡片实例数据的删除。 263 264 265```ts 266import { common } from '@kit.AbilityKit'; 267import { hilog } from '@kit.PerformanceAnalysisKit'; 268import { FormExtensionAbility } from '@kit.FormKit'; 269import { BusinessError } from '@kit.BasicServicesKit'; 270import { preferences } from '@kit.ArkData'; 271 272const TAG: string = 'JsCardFormAbility'; 273const DATA_STORAGE_PATH: string = '/data/storage/el2/base/haps/form_store'; 274const DOMAIN_NUMBER: number = 0xFF00; 275 276let deleteFormInfo = async (formId: string, context: common.FormExtensionContext): Promise<void> => { 277 try { 278 const storage: preferences.Preferences = await preferences.getPreferences(context, DATA_STORAGE_PATH); 279 // del form info 280 await storage.delete(formId); 281 hilog.info(DOMAIN_NUMBER, TAG, `[EntryFormAbility] deleteFormInfo, del form info successfully, formId: ${formId}`); 282 await storage.flush(); 283 } catch (err) { 284 hilog.error(DOMAIN_NUMBER, TAG, `[EntryFormAbility] failed to deleteFormInfo, err: ${JSON.stringify(err as BusinessError)}`); 285 }; 286}; 287 288export default class JsCardFormAbility extends FormExtensionAbility { 289 onRemoveForm(formId: string): void { 290 // 删除卡片实例数据 291 hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onRemoveForm'); 292 // 删除之前持久化的卡片实例数据 293 // 此接口请根据实际情况实现,具体请参考:FormExtAbility Stage模型卡片实例 294 deleteFormInfo(formId, this.context); 295 } 296} 297``` 298 299具体的持久化方法可以参考[轻量级数据存储开发指导](../database/app-data-persistence-overview.md)。 300 301需要注意的是,卡片使用方在请求卡片时传递给提供方应用的Want数据中存在临时标记字段,表示此次请求的卡片是否为临时卡片: 302 303- 常态卡片:卡片使用方会持久化的卡片。 304 305- 临时卡片:卡片使用方不会持久化的卡片,当前卡片使用方不存在临时卡片场景。 306 307由于临时卡片的数据具有非持久化的特殊性,某些场景例如卡片服务框架死亡重启,此时临时卡片数据在卡片管理服务中已经删除,且对应的卡片ID不会通知到提供方,所以卡片提供方需要自己负责清理长时间未删除的临时卡片数据。同时对应的卡片使用方可能会将之前请求的临时卡片转换为常态卡片。如果转换成功,卡片提供方也需要对对应的临时卡片ID进行处理,把卡片提供方记录的临时卡片数据转换为常态卡片数据,防止提供方在清理长时间未删除的临时卡片时,把已经转换为常态卡片的临时卡片信息删除,导致卡片信息丢失。 308 309 310### 卡片数据交互 311 312当卡片应用需要更新数据时(如触发了定时更新或定点更新),卡片应用获取最新数据,并调用updateForm()接口主动触发卡片的更新。 313 314 315```ts 316import { hilog } from '@kit.PerformanceAnalysisKit'; 317import { formBindingData, FormExtensionAbility, formProvider } from '@kit.FormKit'; 318import { BusinessError } from '@kit.BasicServicesKit'; 319 320const TAG: string = 'JsCardFormAbility'; 321const DOMAIN_NUMBER: number = 0xFF00; 322 323export default class EntryFormAbility extends FormExtensionAbility { 324 onUpdateForm(formId: string): void { 325 // 若卡片支持定时更新/定点更新/卡片使用方主动请求更新功能,则提供方需要重写该方法以支持数据更新 326 hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onUpdateForm'); 327 let obj: Record<string, string> = { 328 'title': 'titleOnUpdate', 329 'detail': 'detailOnUpdate' 330 }; 331 let formData: formBindingData.FormBindingData = formBindingData.createFormBindingData(obj); 332 formProvider.updateForm(formId, formData).catch((error: BusinessError) => { 333 hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] updateForm, error:' + JSON.stringify(error)); 334 }); 335 } 336} 337``` 338 339 340### 开发卡片页面 341 342开发者可以使用类Web范式(HML+CSS+JSON)开发JS卡片页面。生成如下卡片页面,可以这样配置卡片页面文件: 343 344 345 346- HML:使用类Web范式的组件描述卡片的页面信息。 347 348 349 ```html 350 <div class="container"> 351 <stack> 352 <div class="container-img"> 353 <image src="/common/widget.png" class="bg-img"></image> 354 </div> 355 <div class="container-inner"> 356 <text class="title">{{title}}</text> 357 <text class="detail_text" onclick="routerEvent">{{detail}}</text> 358 </div> 359 </stack> 360 </div> 361 ``` 362 363- CSS:HML中类Web范式组件的样式信息。 364 365 366 ```css 367 .container { 368 flex-direction: column; 369 justify-content: center; 370 align-items: center; 371 } 372 373 .bg-img { 374 flex-shrink: 0; 375 height: 100%; 376 } 377 378 .container-inner { 379 flex-direction: column; 380 justify-content: flex-end; 381 align-items: flex-start; 382 height: 100%; 383 width: 100%; 384 padding: 12px; 385 } 386 387 .title { 388 font-size: 19px; 389 font-weight: bold; 390 color: white; 391 text-overflow: ellipsis; 392 max-lines: 1; 393 } 394 395 .detail_text { 396 font-size: 16px; 397 color: white; 398 opacity: 0.66; 399 text-overflow: ellipsis; 400 max-lines: 1; 401 margin-top: 6px; 402 } 403 ``` 404 405- JSON:卡片页面中的数据和事件交互。 406 407 408 ```json 409 { 410 "data": { 411 "title": "TitleDefault", 412 "detail": "TextDefault" 413 }, 414 "actions": { 415 "routerEvent": { 416 "action": "router", 417 "abilityName": "EntryAbility", 418 "params": { 419 "message": "add detail" 420 } 421 } 422 } 423 } 424 ``` 425 426 427### 开发卡片事件 428 429卡片支持为组件设置交互事件(action),包括router事件和message事件,其中router事件用于UIAbility跳转,message事件用于卡片开发人员自定义点击事件。 430 431关键步骤说明如下: 432 4331. 在HML中为组件设置onclick属性,其值对应到JSON文件的actions字段中。 434 4352. 设置router事件: 436 437 - action属性值为"router"。 438 - abilityName为跳转目标的UIAbility名(支持跳转FA模型的PageAbility组件和Stage模型的UIAbility组件),如目前DevEco Studio创建的Stage模型的UIAbility默认名为EntryAbility。 439 - params为传递给跳转目标UIAbility的自定义参数,可以按需填写。其值可以在目标UIAbility启动时的want中的parameters里获取。如Stage模型MainAbility的onCreate生命周期里的入参want的parameters字段下获取到配置的参数。 440 4413. 设置message事件: 442 443 - action属性值为"message"。 444 - params为message事件的用户自定义参数,可以按需填写。其值可以在卡片生命周期函数onFormEvent()中的message里获取。 445 446示例如下。 447 448- HML文件 449 450 451 ```html 452 <div class="container"> 453 <stack> 454 <div class="container-img"> 455 <image src="/common/CardWebImg.png" class="bg-img"></image> 456 <image src="/common/CardWebImgMatrix.png" 457 class="bottom-img"/> 458 </div> 459 <div class="container-inner"> 460 <text class="title" onclick="routerEvent">{{ title }}</text> 461 <text class="detail_text" onclick="messageEvent">{{ detail }}</text> 462 </div> 463 </stack> 464 </div> 465 ``` 466 467- CSS文件 468 469 470 ```css 471 .container { 472 flex-direction: column; 473 justify-content: center; 474 align-items: center; 475 } 476 477 .bg-img { 478 flex-shrink: 0; 479 height: 100%; 480 z-index: 1; 481 } 482 483 .bottom-img { 484 position: absolute; 485 width: 150px; 486 height: 56px; 487 top: 63%; 488 background-color: rgba(216, 216, 216, 0.15); 489 filter: blur(20px); 490 z-index: 2; 491 } 492 493 .container-inner { 494 flex-direction: column; 495 justify-content: flex-end; 496 align-items: flex-start; 497 height: 100%; 498 width: 100%; 499 padding: 12px; 500 } 501 502 .title { 503 font-family: HarmonyHeiTi-Medium; 504 font-size: 14px; 505 color: rgba(255, 255, 255, 0.90); 506 letter-spacing: 0.6px; 507 font-weight: 500; 508 width: 100%; 509 text-overflow: ellipsis; 510 max-lines: 1; 511 } 512 513 .detail_text { 514 font-family: HarmonyHeiTi; 515 font-size: 12px; 516 color: rgba(255, 255, 255, 0.60); 517 letter-spacing: 0.51px; 518 font-weight: 400; 519 text-overflow: ellipsis; 520 max-lines: 1; 521 margin-top: 6px; 522 width: 100%; 523 } 524 ``` 525 526- JSON文件 527 528 529 ```json 530 { 531 "data": { 532 "title": "TitleDefault", 533 "detail": "TextDefault" 534 }, 535 "actions": { 536 "routerEvent": { 537 "action": "router", 538 "abilityName": "JSCardEntryAbility", 539 "params": { 540 "info": "router info", 541 "message": "router message" 542 } 543 }, 544 "messageEvent": { 545 "action": "message", 546 "params": { 547 "detail": "message detail" 548 } 549 } 550 } 551 } 552 ``` 553 554 说明: 555 556 "data"中JSON Value支持多级嵌套数据,在更新数据时,需要注意携带完整数据。 557 558 例如:当前卡片显示07.18日Mr.Zhang的课程信息,示例如下。 559 ```ts 560 "data": { 561 "Day": "07.18", 562 "teacher": { 563 "name": "Mr.Zhang", 564 "course": "Math" 565 } 566 } 567 ``` 568 当卡片内容需要更新为07.18日Mr.Li的课程信息时,需要传递待更新的完整数据,不能只传递单个数据项,如只传name或只传course,示例如下。 569 ```ts 570 "teacher": { 571 "name": "Mr.Li", 572 "course": "English" 573 } 574 ``` 575 576 577- 在UIAbility中接收router事件并获取参数 578 579 580 ```ts 581 import UIAbility from '@ohos.app.ability.UIAbility'; 582 import AbilityConstant from '@ohos.app.ability.AbilityConstant'; 583 import Want from '@ohos.app.ability.Want'; 584 import hilog from '@ohos.hilog'; 585 586 const TAG: string = 'EtsCardEntryAbility'; 587 const DOMAIN_NUMBER: number = 0xFF00; 588 589 export default class EtsCardEntryAbility extends UIAbility { 590 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 591 if (want.parameters) { 592 let params: Record<string, Object> = JSON.parse(JSON.stringify(want.parameters.params)); 593 // 获取router事件中传递的info参数 594 if (params.info === 'router info') { 595 // 执行业务逻辑 596 hilog.info(DOMAIN_NUMBER, TAG, `router info: ${params.info}`); 597 } 598 // 获取router事件中传递的message参数 599 if (params.message === 'router message') { 600 // 执行业务逻辑 601 hilog.info(DOMAIN_NUMBER, TAG, `router message: ${params.message}`); 602 } 603 } 604 } 605 }; 606 ``` 607 608- 在FormExtensionAbility中接收message事件并获取参数 609 610 611 ```ts 612 import FormExtension from '@ohos.app.form.FormExtensionAbility'; 613 import hilog from '@ohos.hilog'; 614 615 const TAG: string = 'FormAbility'; 616 const DOMAIN_NUMBER: number = 0xFF00; 617 618 export default class FormAbility extends FormExtension { 619 onFormEvent(formId: string, message: string): void { 620 // 若卡片支持触发事件,则需要重写该方法并实现对事件的触发 621 hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onFormEvent'); 622 // 获取message事件中传递的detail参数 623 let msg: Record<string, string> = JSON.parse(message); 624 if (msg.detail === 'message detail') { 625 // 执行业务逻辑 626 hilog.info(DOMAIN_NUMBER, TAG, 'message info:' + msg.detail); 627 } 628 } 629 }; 630 ``` 631<!--Del--> 632## 相关实例 633 634针对卡片开发,有以下相关实例可供参考: 635 636- [JS多设备自适应服务卡片(JS)(API9)](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/AdaptiveServiceWidget) 637 638- [电影卡片(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Card/MovieCard) 639 640- [计步器卡片(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Card/StepsCardJS) 641<!--DelEnd-->