Best practice of retrieving params and queryParams

2019-04-04 06:57发布

I'm trying to understand the way of creating a route, with some information in it's URL parameters.

This is my route (app.routes.ts):

{path: 'results/:id', component: MyResultsComponent},

This is how I navigate to the route :

goToResultsPage(query: string) {
this.router.navigate(['results', query], { queryParams: { pageSize: 20 } });}

As you can see, I've also a query parameter. I was wondering, what is the best and cleanest way to retrieve this in my MyResultsComponent. Right now I've kind of a nested subscribe structure:

ngOnInit() {
    this.route
      .params
      .subscribe(params => {
        this.query = params['id'];
        this.route
          .queryParams
          .subscribe(queryParams => {
            this.offset = queryParams['pageSize'];
            #find entries this.entryService.findEntries(this.query, this.pageSize);
      });
    });
  }

Afterwards, I want to pass this parameters to my EntryService, which returns the found entries.

4条回答
贪生不怕死
2楼-- · 2019-04-04 07:21

The Observable.combineLatest is a solution in this situation, isn't it?

Observable
  .combineLatest(
    this.route.params,
    this.route.queryParams,
    (params: any, queryParams: any) => {
      return {
        id: +params.id,
        pageSize: queryParams.pageSize ? +queryParams.pageSize: null
      }
    })
  .subscribe(bothParams => {
    this.id = bothParams.id;
    this.pageSize = bothParams.pageSize;
  });
查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-04-04 07:23

I've faced this dilemma recently and the best solution fitting my needs I've found is to use Observable.merge.

Using snapshot is not good if you want to watch changes from params queryParams within the same component (i.e search with filters).

Observable.forkJoin has the limitation that both observables must be triggered in order to work, so if you have a scenario where there might be changes in params or in queryParams, but not necessarily in both, forkJoin wouldn't hep you.

Observable.merge on the other hand is triggered with either one of them being triggered. Of course, this also has some drawbacks since you might have two callbacks being called one after the other (at the beginning with params and queryParams).

Here is an example:

Observable.merge(
  this.route.params.map(params => this.handleParams(params)),
  this.route.queryParams.map(queryParams => this.handleQueryParams(queryParams))
)
.subscribe(
  () => this.onParamsOrQueryParamsChange()
);
查看更多
仙女界的扛把子
4楼-- · 2019-04-04 07:25

What about using a forkJoin?

ForkJoin allows you to join two observables and wait for the response of both them. You can see the documentation here and read more about it here.

As for your code it would look something like this:

ngOnInit() {
    Observable.forkJoin(this.route.params, this.route.queryParams).subscribe(bothParams => {
        // bothParams is an array, on the first index we have the router.params 
        // on the second index we have the queryParams
        this.query = bothParams[0].query;
        this.pageSize = bothParams[0].pageSize;
        this.entryService.findEntries(this.query, this.pageSize);
    });
  }

You might need to add imports:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
查看更多
疯言疯语
5楼-- · 2019-04-04 07:29

I guess if you need to access both at the same time the snapshot is a better option.

Not tested (just from the top of my head)

ngOnInit() {
    this.route
      .params
      .subscribe(params => {
        this.query = params['id'];
        this.offset = this.route.snapshot.queryParams['pageSize'];
        # find entries this.entryService.findEntries(this.query, this.pageSize);
      });
    });
  }
查看更多
登录 后发表回答