Combine route and query parameters in Angular

不问归期 提交于 2020-01-04 09:17:25

问题


In Angular I have to process a route in the format

/sections/{id}?filter={filter}

i.e. I have a route parameter (id), and a query parameter (filter). Both parameters are optional, so all of these routes are valid and being listened to

/sections/{id}?filter={filter}
/sections?filter={filter}
/sections/{id}
/sections

When handling a route I need to call a potentially expensive service, providing the parameters given. I can subscribe to both the params and queryParams of the route, but I want only to call the service once per url change, avoiding any unneeded calls.

The problem is that when moving from /sections/1?filter=active to /sections/2 both observables will trigger, and I cannot control which one will trigger first. On the other hand, when moving from /sections/1?filter=active to /sections/1, or from /sections/1?filter=active to /sections/2?filter=active, only one will be triggered.

Is there any sane way to know when the last subscription triggers, so that I can avoid sending unneeded server calls?


The test code so far looks something like:

constructor(private activeRoute: ActivatedRoute, private dataService: dataService) {

    this.activeRoute.paramMap.subscribe((params: ParamMap) => {
        console.log("triggering route params subscription");
        this.section = params.get("id");
        this.dataService.runSlowQuery(this.section, this.filter);
    });

    this.activeRoute.queryParamMap.subscribe((queryParams: ParamMap) => {
        console.log("triggering query params subscription");
        this.filter = queryParams.get("filter");
        this.dataService.runSlowQuery(this.section, this.filter);
    });
}

回答1:


1. Subscribe to router event

You can subscribe to router events. This will give you access to the UrlTree object which allows for more flexibility.

import { Router, UrlTree, NavigationEnd } from '@angular/router';

...

constructor(private router: Router) {}

...

let navigation = this.router.events
   .filter(navigation => navigation instanceof NavigationEnd)
   .map((navigation) => {
     let urlTree = this.router.parseUrl(navigation['url']);
     let queryParams = urlTree.queryParams;
     let segments = urlTree.root.children['primary'] ? urlTree.root.children['primary'].segments : null;
     return { queryParams: queryParams, segments: segments }
   });

navigation.subscribe((navigation) => { ... });

2. Make use of combineLatest

let params = this.activeRoute.paramMap;
let queryParams = this.activeRoute.queryParamMap;
let navigation = Observable
   .combineLatest(params, queryParams, (params, queryParams) => ({ params, queryParams }));

navigation.subscribe((navigation) => { ... });


来源:https://stackoverflow.com/questions/47176328/combine-route-and-query-parameters-in-angular

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!