【问题标题】:Ionic 4 - how to pass data between pages using navCtrl or Router serviceIonic 4 - 如何使用 navCtrl 或路由器服务在页面之间传递数据
【发布时间】:2019-02-10 17:25:46
【问题描述】:

在 Ionic 3 中,您可以使用 navController 的第二个参数将数据传递到下一页并使用 navParams 服务检索它。

这是一个非常方便的功能。 Ionic 4 中是否有等效的路由 API?

您始终可以将对象/数组 JSON.stringify 到 routerParams,我认为这不太方便。

在 Ionic 4 中,您可以使用 ComponentProps 和 @Input() 向 modalController 传递数据,使其更适合快速推送/弹出实现。

编辑

我对这个问题的意图是找出是否有来自 Angular 6+ 或 Ionic 4+ 的本机 API。我很清楚如何实现自定义服务或解析器来完成此任务。

我们的目标是充分利用 ionic 和 angular 的 api,因为在大型项目中,每个自定义代码都需要文档并增加复杂性。

【问题讨论】:

  • 感谢您的建议,但正如我刚刚编辑的那样,您始终可以将字符串化对象/数组传递给参数。不过 ionic3 之前的 navController 更方便
  • 也许另一种选择是使用 rxjs/Subject 创建一个调解器来保存事件值
  • 如果您想在应用程序中的组件之间传递数据,最好的选择是使用 rxjs/Subject 并通过服务传递信息,如果这是什么,我可以创建一个示例作为答案你想要的。
  • @Araldy 谢谢,但这不是我要找的答案。想法是利用默认功能来增加我们团队之间的代码透明度。每次启动新服务都会增加不必要的复杂性

标签: angular ionic-framework angular-routing ionic4


【解决方案1】:

在 Ionic v4 / Angular 7.2+ 中有多种方法可以将参数从一个页面传递到另一个页面:

1.使用 Extras 状态(Angular 7.2 之后的新功能) - 推荐

简单干净

// original page
let navigationExtras: NavigationExtras = { state: { foo: this.foo } };
this.router.navigate(['destination-path'], navigationExtras);
// destination page
constructor(private route: ActivatedRoute, private router: Router) {
    this.route.queryParams.subscribe(params => {
      if (this.router.getCurrentNavigation().extras.state) {
        this.foo= this.router.getCurrentNavigation().extras.state.foo;
      }
    });
  }

2。使用服务和解析器

不影响数据,但有点重。

将数据存储到服务中并使用路由器传递解析器

3.使用对象的 id(不推荐)

如果你的对象被存储了,你可以在url中传递id并再次获取它。

这会减慢应用程序的速度,暗示对象存储在某处并可能增加网络问题(如果不存储在本地)

4.使用查询参数(不推荐)

通过 stringyfing 你的对象:查看@Tahseen Quraishi 的回答

只能传递很少的信息,而且网址很丑

Some examples here

【讨论】:

  • 如果你使用 Extras,你需要从 "@angular/router" 导入 { Router, NavigationExtras };
  • 如果我想使用 Ionic 的 NavController.navigateForward(它使用 Angular 的底层路由器?
【解决方案2】:

我通过将 Ionic NavController 包装在一个提供程序中解决了这个问题,该提供程序具有为变量设置值和再次获取它的函数。类似于this.navParams.get('myItem')

看看下面的内容;

import { Injectable } from '@angular/core';
import { NavController } from '@ionic/angular';

@Injectable()
export class Nav {
    data: any;

    constructor(public navCtrl: NavController) {
        // ...
    }

    push(url: string, data: any = '') {
        this.data = data;

        this.navCtrl.navigateForward('/' + url);
    }

    pop(url) {
        this.navCtrl.navigateBack('/' + url);
    }

    get(key: string) {
        return this.data[key];
    }
}

希望这会有所帮助!

【讨论】:

  • 感谢您的建议,这也是我的后备方法。但正如我在上面的评论中提到的,在更大的项目和团队中工作时使用默认 API 很重要。您编写的每个自定义服务都会产生复杂性和文档工作
  • 当然,我明白了,但到目前为止,这似乎是最好的方法,除非你想使用不太支持离子动画的 angulars router.navigate。
  • NavParams 在 ionic 4 中不可用。
【解决方案3】:

您可以使用 queryParams 简单地通过 route 传递 object

import { Router } from '@angular/router';

      object = {
            name: 'subham',
            age: '34',
            address: '34 street, Delhi, India'
            }

      constructor(public router : Router) {}

            onGoToNextPage(){
            this.router.navigate(['/pageName'],{
            queryParams: this.object,
            });
          }

要接收这个object,您需要使用从'@angular/router'

导入的ActivatedRoute
import { ActivatedRoute } from '@angular/router';


 constructor(public activatedRoute : ActivatedRoute,) { 

                this.activatedRoute.queryParams.subscribe((res)=>{
                  console.log(res);
              });
              }

如果您的对象结构复杂很少。

假设您有以下对象要发送。

object = {
                name: 'subham',
                age: '34',
                address: '34 street, Delhi, India'
                favourite_movie: ['dhoom','race 2','krishh'],
                detail : {
                  height: '6ft',
                  weight: '70kg'
                 }
                }

要发送上述object,您需要先在JSON.stringfy()的帮助下stringify对象。

   import { Router } from '@angular/router';

          object = {
                    name: 'subham',
                    age: '34',
                    address: '34 street, Delhi, India'
                    favourite_movie: ['dhoom','race 2','krishh'],
                    detail : {
                      height: '6ft',
                      weight: '70kg',
                     }
                    }

          constructor(public router : Router) {}

                onGoToNextPage(){
                this.router.navigate(['/pageName'],{
                queryParams: {
                   value : JSON.stringify(this.object)
                  },
                });
              }

要接收此对象,您需要使用 JSON.parse() 方法解析此对象。

import { ActivatedRoute } from '@angular/router';


 constructor(public activatedRoute : ActivatedRoute,) { 

                this.activatedRoute.queryParams.subscribe((res)=>{
                  console.log(JSON.parse(res.value));
              });
              }

【讨论】:

    【解决方案4】:

    实际上有很多方法可以在页面之间传递数据。我试过RoutenavCtrl 但是,它对我不起作用。我正在分享一种使用SERVICE 传递数据的方法。

    1. 在您的 ionic 项目上创建一个服务,或者您也可以对 Angular 项目执行相同的步骤(只有命令会改变):
      $ ionic generate provider <any name>
    
    1. 将此代码放在您的服务 TS 文件中。
      import { Injectable } from "@angular/core";
      import { map } from "rxjs/operators";
      import { BehaviorSubject } from "rxjs";  
    
      @Injectable({ providedIn: "root" })
    
      export class <your_class_name_here> {
        constructor() {}
    
        private dataSource = new BehaviorSubject("default message");
        serviceData = this.dataSource.asObservable();
    
        changeData(data: any) {
          this.dataSource.next(data);
        }
      }
    
    1. 在两个页面上导入服务,从哪里获取数据以及从哪里获取数据。像这样。
      import { UserService } from "./../services/user.service";
    
      constructor(
        private userServ: UserService,
      ) {}
    
    1. 这样设置您的数据:
      this.userServ.changeData(responceData.data);
    
    1. 这样获取您的数据:
      sentData: any;
    
      ngOnInit() {
        this.userServ.serviceData
          .subscribe(data => (this.sentData = data));
        console.log("sent data from login page : ", this.sentData);
      }
    

    这对我有用。

    【讨论】:

    • 我们可以使用事件共享来在一个页面之间共享数据到另一个页面吗?
    • 如果您要传递不会更改的数据,使用getset 方法可能会更简单,而不是changeDatasubscribe
    • 是的,这是不可能的。但我更喜欢这种方式。
    【解决方案5】:

    我已经解决了

    您可以使用 JSON.stringify 简单地通过路由传递对象数据。

    this.router.navigate(['namepage',JSON.stringify(data)]);
    

    要接收此对象,您需要使用 JSON.parse() 方法解析此对象。

    items: any;
    
    this.items = JSON.parse(this.activatedRoute.snapshot.paramMap.get('id'));
    

    为了可视化数据,我们附加了保存字段的名称

    this.idxxx = this.items.namefield;
    

    必须先在app.routing.module.ts中定义参数

    const routes: Routes = [
      { path: '', redirectTo: 'login', pathMatch: 'full' },
      { path: 'namepage/:id', loadChildren: './pages/page/page.module#pagePageModule' },
    ];
    

    希望对你有帮助,这确实是最简单的方法

    【讨论】:

    • 它不使用 Ionic 的 NavController,而是使用 Angular 的 Router。
    【解决方案6】:

    我从第一个测试版开始就一直在使用 Ionic 4,但我还没有找到您要找的东西。我相信 Ionic 团队希望将组件交互的任务交给组件框架(Angular、React、Vue...)。

    如果您想降低复杂性,您可以使用 Angular 服务、redux 或 ngrx 来管理应用程序的状态。通过这种方式,您可以导航到视图,通过操作更新全局状态,然后返回上一个视图并显示更新后的状态。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-19
      • 2021-04-12
      • 1970-01-01
      • 2019-09-11
      • 1970-01-01
      相关资源
      最近更新 更多