文档管理中心

Navigation使用replacePath跳转后,如何携带数据返回到栈内上一个页面

问题现象

PageA通过pushPath跳转到PageB,PageB通过replacePath方式跳转到PageB,如何在PageB回到PageA的时候把数据返回到PageA。

背景知识

  • pushPath:将指定的NavDestination页面信息入栈,通过NavigationOptions设置页面栈操作选项。
  • NavPathInfo:路由页面信息。
  • replacePath:将当前页面栈栈顶退出,将info指定的NavDestination页面信息入栈。
  • onPop:接收入栈页面出栈时的返回结果。
  • onResult:NavDestination返回时触发该回调。

解决方案

  • 方案一:可以将onPop封装成通用方法,PageA跳转到PageB时,将此方法携带过去,当PageB通过replacePath方式跳转到PageB时,绑定的onPop使用传递进来的方法。
    收起
    自动换行
    深色代码主题
    复制
    1. import { PageA } from './PageAS1';
    2. import { PageB } from './PageBS1';
    3. @Entry
    4. @Component
    5. struct Solution1 {
    6. @Provide pathStack: NavPathStack = new NavPathStack();
    7. @Builder
    8. pageMap(params: string) {
    9. if (params === 'PageA') {
    10. PageA();
    11. } else if (params === 'PageB') {
    12. PageB();
    13. }
    14. }
    15. build() {
    16. Navigation(this.pathStack) {
    17. Column() {
    18. Button('Push PageA')
    19. .onClick(() => {
    20. this.pathStack.pushPathByName('PageA', null);
    21. });
    22. }.width('100%').height('100%')
    23. .justifyContent(FlexAlign.Center);
    24. }.navDestination(this.pageMap);
    25. }
    26. }
    收起
    自动换行
    深色代码主题
    复制
    1. @ObservedV2
    2. export class Params {
    3. @Trace num: number = 0;
    4. click: (popInfo: PopInfo) => void = () => {
    5. };
    6. }
    7. @Component
    8. export struct PageA {
    9. @Consume pathStack: NavPathStack;
    10. private param: Params = new Params();
    11. // 封装的onPop回调
    12. customOnPop = (popInfo: PopInfo) => {
    13. this.param.num = popInfo.result as number;
    14. };
    15. aboutToAppear(): void {
    16. // 初始化参数
    17. this.param.num = 0;
    18. this.param.click = this.customOnPop;
    19. }
    20. build() {
    21. NavDestination() {
    22. Column() {
    23. Column() {
    24. Text('One Page')
    25. .fontSize('30');
    26. Text(`${this.param.num}`)
    27. .fontSize('30');
    28. }
    29. .justifyContent(FlexAlign.Center)
    30. .size({ width: '100%', height: '60%' });
    31. Row() {
    32. Button('push PageB')
    33. .onClick(() => {
    34. this.pathStack.pushPath({
    35. name: 'PageB', param: this.param, onPop: (popInfo) => {
    36. this.param.click(popInfo); // 使用封装的onPop回调
    37. }
    38. });
    39. });
    40. }.justifyContent(FlexAlign.SpaceAround)
    41. .alignItems(VerticalAlign.Center)
    42. .size({ width: '100%', height: '40%' });
    43. };
    44. }.width('100%').height('100%');
    45. }
    46. }
    收起
    自动换行
    深色代码主题
    复制
    1. import { Params } from './PageAS1';
    2. @Component
    3. export struct PageB {
    4. @Consume pathStack: NavPathStack;
    5. private param: Params = new Params();
    6. build() {
    7. NavDestination() {
    8. Column() {
    9. Row() {
    10. Text('Second Page')
    11. .fontSize('30');
    12. }
    13. .justifyContent(FlexAlign.Center)
    14. .alignItems(VerticalAlign.Center)
    15. .size({ width: '100%', height: '60%' });
    16. Column() {
    17. Button('Replace PageB')
    18. .onClick(() => {
    19. this.pathStack.replacePath({
    20. name: 'PageB', onPop: (popInfo) => {
    21. this.param.click(popInfo); // 使用传递过来的方法
    22. }
    23. });
    24. });
    25. Button('pop back')
    26. .onClick(() => {
    27. this.pathStack.pop(10);
    28. });
    29. }.size({ width: '100%', height: '40%' });
    30. };
    31. }.width('100%').height('100%')
    32. .onReady((ctx: NavDestinationContext) => {
    33. this.param = ctx?.pathInfo?.param as Params; // 接收传递的参数
    34. });
    35. }
    36. }
  • 方案二:使用onResult来处理页面返回,在PageA的NavDestination添加onResult回调,用来接收返回到该页面时携带的数据。下述示例中Navigation页面代码同方案一。
    收起
    自动换行
    深色代码主题
    复制
    1. @ObservedV2
    2. export class Params {
    3. @Trace num: number = 0;
    4. }
    5. @Component
    6. export struct PageA {
    7. @Consume pathStack: NavPathStack;
    8. private param: Params = new Params();
    9. aboutToAppear(): void {
    10. this.param.num = 0;
    11. }
    12. build() {
    13. NavDestination() {
    14. Column() {
    15. Column() {
    16. Text('One Page')
    17. .fontSize('30');
    18. Text(`${this.param.num}`)
    19. .fontSize('30');
    20. }.justifyContent(FlexAlign.Center)
    21. .size({ width: '100%', height: '60%' });
    22. Row() {
    23. Button('push PageB')
    24. .onClick(() => {
    25. this.pathStack.pushPath({ name: 'PageB' });
    26. });
    27. }.justifyContent(FlexAlign.SpaceAround)
    28. .alignItems(VerticalAlign.Center)
    29. .size({ width: '100%', height: '40%' });
    30. };
    31. }
    32. .onResult((num: number) => {
    33. this.param.num = num; // 接收回到此页面携带的参数
    34. }).size({ width: '100%', height: '100%' });
    35. }
    36. }
    收起
    自动换行
    深色代码主题
    复制
    1. @Component
    2. export struct PageB {
    3. @Consume pathStack: NavPathStack;
    4. build() {
    5. NavDestination() {
    6. Column() {
    7. Row() {
    8. Text('Second Page')
    9. .fontSize('30');
    10. }
    11. .justifyContent(FlexAlign.Center)
    12. .alignItems(VerticalAlign.Center)
    13. .size({ width: '100%', height: '60%' });
    14. Column() {
    15. Button('Replace PageB')
    16. .onClick(() => {
    17. this.pathStack.replacePath({ name: 'PageB' });
    18. });
    19. Button('pop back')
    20. .onClick(() => {
    21. this.pathStack.pop(10);
    22. });
    23. }.size({ width: '100%', height: '40%' });
    24. };
    25. }.size({ width: '100%', height: '100%' });
    26. }
    27. }

常见FAQ

Q:Navigation使用pop跳转至单例页面时,如何重置目标页面的参数信息。

A:pop不可以重置param参数,pushPath默认的路由栈操作模式为STANDARD,将指定的NavDestination入栈,如果需要重置目标页面参数,需要使用pushPath指定页面栈操作模式为POP_TO_SINGLETON或MOVE_TO_TOP_SINGLETON,并传递新的参数,就可以实现和pop一样的效果并且能够重置param参数。

Q:对于单例页面,如何处理单例页面的数据接收问题?

A:HarmonyOS的onNewParam是当之前存在于栈中的NavDestination页面通过launchMode.MOVE_TO_TOP_SINGLETON或launchMode.POP_TO_SINGLETON移动到栈顶时,触发该回调,可基于此接收新数据。

在 FAQ 中进行搜索
请输入您想要搜索的关键词