• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   ![en-us_image_0000001223127744](figures/en-us_image_0000001223127744.gif)
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   ![en-us_image_0000001267607909](figures/en-us_image_0000001267607909.gif)
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   ![en-us_image_0000001267767881](figures/en-us_image_0000001267767881.png)
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