1# Implementing Page Redirection and Data Transmission 2 3 4This section describes how to implement page redirection and data transmission between pages: 5 6 71. Page redirection: Click a food item on the food list page to go to the food details page. Click the back button on the food details page to go back to the food list page. 8 92. Data transmission between pages: After you click a food item, FoodDetail receives data from the previous page and renders the corresponding food details page. 10 11 12## Page Redirection 13 14The declarative UI paradigm provides two mechanisms for page redirection: 15 161. Navigator: encapsulates the page routing capability. After the page target is specified, all child components in the page target have the routing capability. 17 182. Router APIs: called to implement various operations of page routing. You'll need to import router before calling the router APIs. 19 20The procedure below uses these two mechanisms for redirection between the page list page and food details page. 21 221. Click FoodListItem. The FoodDetail page is displayed. Create a Navigator component in FoodListItem to enable its child components to have the routing function. The target page is 'pages/FoodDetail'. 23 24 ``` 25 @Component 26 struct FoodListItem { 27 private foodItem: FoodData 28 build() { 29 Navigator({ target: 'pages/FoodDetail' }) { 30 Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { 31 Image(this.foodItem.image) 32 .objectFit(ImageFit.Contain) 33 .height(40) 34 .width(40) 35 .backgroundColor('#FFf1f3f5') 36 .margin({ right: 16 }) 37 Text(this.foodItem.name) 38 .fontSize(14) 39 .flexGrow(1) 40 Text(this.foodItem.calories + ' kcal') 41 .fontSize(14) 42 } 43 .height(64) 44 } 45 .margin({ right: 24, left:32 }) 46 } 47 } 48 ``` 49 50  51 522. Click FoodGridItem. The FoodDetail page is displayed. Import the router module, and then call the push API of this module to push the FoodDetail page to the route stack to implement page redirection. 53 54 ``` 55 import router from '@system.router' 56 57 @Component 58 struct FoodGridItem { 59 private foodItem: FoodData 60 build() { 61 Column() { 62 ...... 63 } 64 .height(184) 65 .width('100%') 66 .onClick(() => { 67 router.push({ uri: 'pages/FoodDetail' }) 68 }) 69 } 70 } 71 ``` 72 73  74 753. Add the icon for returning from the FoodDetail page to the food list page. Save the Back.png file to the resources > base > media directory. Create a custom component PageTitle, which contains the back icon and Food Detail text. Call the router.back() API of the router to display the top page of the route stack, that is, the upper-level page. 76 77 ``` 78 // FoodDetail.ets 79 import router from '@system.router' 80 81 @Component 82 struct PageTitle { 83 build() { 84 Flex({ alignItems: ItemAlign.Start }) { 85 Image($r('app.media.Back')) 86 .width(21.8) 87 .height(19.6) 88 Text('Food Detail') 89 .fontSize(21.8) 90 .margin({left: 17.4}) 91 } 92 .height(61) 93 .backgroundColor('#FFedf2f5') 94 .padding({ top: 13, bottom: 15, left: 28.3 }) 95 .onClick(() => { 96 router.back() 97 }) 98 } 99 } 100 ``` 101 1024. Create the Stack component in the FoodDetail component, including the FoodImageDisplay and PageTitle child components. Set the alignment mode to TopStart. 103 104 ``` 105 @Entry 106 @Component 107 struct FoodDetail { 108 build() { 109 Column() { 110 Stack( { alignContent: Alignment.TopStart }) { 111 FoodImageDisplay() 112 PageTitle() 113 } 114 ContentTable() 115 } 116 .alignItems(HorizontalAlign.Center) 117 } 118 } 119 ``` 120 121  122 123 124## Data Transmission Between Pages 125 126We have implemented the redirection and going back of the FoodCategoryList and FoodDetail pages. At this point, the tomato details page is displayed no matter which FoodListItem/FoodGridItem is clicked. This is because the data transmission between pages is not yet configured. To configure data transmission between pages, set the routing with parameters as follows: 127 1281. Set the params attribute in the Navigator of the FoodListItem component. The params attribute accepts the key-value object. 129 130 ``` 131 // FoodList.ets 132 @Component 133 struct FoodListItem { 134 private foodItem: FoodData 135 build() { 136 Navigator({ target: 'pages/FoodDetail' }) { 137 ...... 138 } 139 .params({ foodData: this.foodItem }) 140 } 141 } 142 ``` 143 144 The router API called by FoodGridItem also has the capability of redirection with parameters. The method of using the router API is similar to that of using the Navigator. 145 146 147 ``` 148 router.push({ 149 uri: 'pages/FoodDetail', 150 params: { foodData: this.foodItem } 151 }) 152 ``` 153 1542. Import the FoodData class to the FoodDetail page and add the foodItem member variable to the FoodDetail component. 155 156 ``` 157 // FoodDetail.ets 158 import { FoodData } from '../model/FoodData' 159 160 @Entry 161 @Component 162 struct FoodDetail { 163 private foodItem: FoodData 164 build() { 165 ...... 166 } 167 } 168 ``` 169 1703. Obtain the value of foodData. Call router.getParams().foodData to obtain the data corresponding to foodData carried when the FoodCategoryList page is displayed. 171 172 ``` 173 @Entry 174 @Component 175 struct FoodDetail { 176 private foodItem: FoodData = router.getParams().foodData 177 178 build() { 179 ...... 180 } 181 } 182 ``` 183 1844. Re-build the components on the FoodDetail page. During building, the food information on the FoodDetail page is all directly declared constants. You need to use the passed FoodData data to assign a new value to the constants. The code is as follows: 185 186 ``` 187 @Component 188 struct PageTitle { 189 build() { 190 Flex({ alignItems: ItemAlign.Start }) { 191 Image($r('app.media.Back')) 192 .width(21.8) 193 .height(19.6) 194 Text('Food Detail') 195 .fontSize(21.8) 196 .margin({left: 17.4}) 197 } 198 .height(61) 199 .backgroundColor('#FFedf2f5') 200 .padding({ top: 13, bottom: 15, left: 28.3 }) 201 .onClick(() => { 202 router.back() 203 }) 204 } 205 } 206 207 @Component 208 struct FoodImageDisplay { 209 private foodItem: FoodData 210 build() { 211 Stack({ alignContent: Alignment.BottomStart }) { 212 Image(this.foodItem.image) 213 .objectFit(ImageFit.Contain) 214 Text(this.foodItem.name) 215 .fontSize(26) 216 .fontWeight(500) 217 .margin({ left: 26, bottom: 17.4 }) 218 } 219 .height(357) 220 .backgroundColor('#FFedf2f5') 221 } 222 } 223 224 @Component 225 struct ContentTable { 226 private foodItem: FoodData 227 228 @Builder IngredientItem(title:string, name: string, value: string) { 229 Flex() { 230 Text(title) 231 .fontSize(17.4) 232 .fontWeight(FontWeight.Bold) 233 .layoutWeight(1) 234 Flex() { 235 Text(name) 236 .fontSize(17.4) 237 .flexGrow(1) 238 Text(value) 239 .fontSize(17.4) 240 } 241 .layoutWeight(2) 242 } 243 } 244 245 build() { 246 Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Start }) { 247 this.IngredientItem('Calories', 'Calories', this.foodItem.calories + 'kcal') 248 this.IngredientItem('Nutrition', 'Protein', this.foodItem.protein + 'g') 249 this.IngredientItem('', 'Fat', this.foodItem.fat + 'g') 250 this.IngredientItem('', 'Carbohydrates', this.foodItem.carbohydrates + 'g') 251 this.IngredientItem('', 'VitaminC', this.foodItem.vitaminC + 'mg') 252 } 253 .height(280) 254 .padding({ top: 30, right: 30, left: 30 }) 255 } 256 } 257 258 @Entry 259 @Component 260 struct FoodDetail { 261 private foodItem: FoodData = router.getParams().foodData 262 263 build() { 264 Column() { 265 Stack( { alignContent: Alignment.TopStart }) { 266 FoodImageDisplay({ foodItem: this.foodItem }) 267 PageTitle() 268 } 269 ContentTable({ foodItem: this.foodItem }) 270 } 271 .alignItems(HorizontalAlign.Center) 272 } 273 } 274 ``` 275