1# Redirecting to a UIAbility Through the router Event 2 3The **router** capability of the [postCardAction](../reference/apis-arkui/js-apis-postCardAction.md#postcardaction) API can be used in a widget to quickly start a specific UIAbility of the widget provider. By leveraging this capability, an application can provide in the widget multiple buttons, each of which targets a different target UIAbility. For example, a camera widget can provide the buttons that redirect the user to the UIAbility for taking a photo and the UIAbility for recording a video. 4 5 6 7> **NOTE** 8> 9> This topic describes development for dynamic widgets. For static widgets, see [FormLink](../reference/apis-arkui/arkui-ts/ts-container-formlink.md). 10 11 12Generally, a button is used to start a page. Below is an example: 13 14 15- Design two buttons on the widget page. When one of the buttons is clicked, **postCardAction** is called to send a router event to the specified UIAbility, with the content to be transferred defined in the event. 16 17 ```ts 18 @Entry 19 @Component 20 struct WidgetEventRouterCard { 21 build() { 22 Column() { 23 Text($r('app.string.JumpLabel')) 24 .fontColor('#FFFFFF') 25 .opacity(0.9) 26 .fontSize(14) 27 .margin({ top: '8%', left: '10%' }) 28 Row() { 29 Column() { 30 Button() { 31 Text($r('app.string.ButtonA_label')) 32 .fontColor('#45A6F4') 33 .fontSize(12) 34 } 35 .width(120) 36 .height(32) 37 .margin({ top: '20%' }) 38 .backgroundColor('#FFFFFF') 39 .borderRadius(16) 40 .onClick(() => { 41 postCardAction(this, { 42 action: 'router', 43 abilityName: 'EntryAbility', 44 params: { targetPage: 'funA' } 45 }); 46 }) 47 48 Button() { 49 Text($r('app.string.ButtonB_label')) 50 .fontColor('#45A6F4') 51 .fontSize(12) 52 } 53 .width(120) 54 .height(32) 55 .margin({ top: '8%', bottom: '15vp' }) 56 .backgroundColor('#FFFFFF') 57 .borderRadius(16) 58 .onClick(() => { 59 postCardAction(this, { 60 action: 'router', 61 abilityName: 'EntryAbility', 62 params: { targetPage: 'funB' } 63 }); 64 }) 65 } 66 }.width('100%').height('80%') 67 .justifyContent(FlexAlign.Center) 68 } 69 .width('100%') 70 .height('100%') 71 .alignItems(HorizontalAlign.Start) 72 .backgroundImage($r('app.media.CardEvent')) 73 .backgroundImageSize(ImageSize.Cover) 74 } 75 } 76 ``` 77 78- The UIAbility receives the router event and obtains parameters. It then starts the page specified by **params**. 79 80 ```ts 81 import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 82 import { window } from '@kit.ArkUI'; 83 import { hilog } from '@kit.PerformanceAnalysisKit'; 84 85 const TAG: string = 'EntryAbility'; 86 const DOMAIN_NUMBER: number = 0xFF00; 87 88 export default class EntryAbility extends UIAbility { 89 private selectPage: string = ''; 90 private currentWindowStage: window.WindowStage | null = null; 91 92 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 93 // Obtain the targetPage parameter passed in the router event. 94 hilog.info(DOMAIN_NUMBER, TAG, `Ability onCreate: ${JSON.stringify(want?.parameters)}`); 95 if (want?.parameters?.params) { 96 // want.parameters.params corresponds to params in postCardAction(). 97 let params: Record<string, Object> = JSON.parse(want.parameters.params as string); 98 this.selectPage = params.targetPage as string; 99 hilog.info(DOMAIN_NUMBER, TAG, `onCreate selectPage: ${this.selectPage}`); 100 } 101 } 102 103 // If the UIAbility is running in the background, the onNewWant lifecycle callback is triggered after the router event is received. 104 onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { 105 hilog.info(DOMAIN_NUMBER, TAG, `Ability onNewWant: ${JSON.stringify(want?.parameters)}`); 106 if (want?.parameters?.params) { 107 // want.parameters.params corresponds to params in postCardAction(). 108 let params: Record<string, Object> = JSON.parse(want.parameters.params as string); 109 this.selectPage = params.targetPage as string; 110 hilog.info(DOMAIN_NUMBER, TAG, `onNewWant selectPage: ${this.selectPage}`); 111 } 112 if (this.currentWindowStage !== null) { 113 this.onWindowStageCreate(this.currentWindowStage); 114 } 115 } 116 117 onWindowStageCreate(windowStage: window.WindowStage): void { 118 // Main window is created, set main page for this ability 119 let targetPage: string; 120 // Start the page specified by targetPage. 121 switch (this.selectPage) { 122 case 'funA': 123 targetPage = 'pages/FunA'; 124 break; 125 case 'funB': 126 targetPage = 'pages/FunB'; 127 break; 128 default: 129 targetPage = 'pages/Index'; 130 } 131 if (this.currentWindowStage === null) { 132 this.currentWindowStage = windowStage; 133 } 134 windowStage.loadContent(targetPage, (err, data) => { 135 if (err.code) { 136 hilog.error(DOMAIN_NUMBER, TAG, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); 137 return; 138 } 139 hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); 140 }); 141 } 142 } 143 ``` 144