在 Angular 中组合路由和查询参数

SWe*_*eko 5 observable angular angular-router

在 Angular 中,我必须处理以下格式的路线

/sections/{id}?filter={filter}
Run Code Online (Sandbox Code Playgroud)

即我有一个路由参数(id)和一个查询参数(filter)。两个参数都是可选的,因此所有这些路由都是有效的并且正在被监听

/sections/{id}?filter={filter}
/sections?filter={filter}
/sections/{id}
/sections
Run Code Online (Sandbox Code Playgroud)

处理路线时,我需要调用可能昂贵的服务,并提供给定的参数。我可以订阅路由的paramsqueryParams,但我只想在每次 url 更改时调用该服务一次,从而避免任何不必要的调用。

问题是,当从 移动/sections/1?filter=active到时/sections/2,两个可观察量都会触发,而我无法控制哪个将首先触发。另一方面,当从/sections/1?filter=active/sections/1或从移动/sections/1?filter=active到时/sections/2?filter=active,只会触发一个。

有没有什么明智的方法可以知道最后一次订阅何时触发,以便我可以避免发送不需要的服务器调用?


到目前为止的测试代码看起来像这样:

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);
    });
}
Run Code Online (Sandbox Code Playgroud)

uni*_*rio 5

1.订阅路由器事件

您可以订阅路由器events。这将使您能够访问该UrlTree对象,从而具有更大的灵活性。

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) => { ... });
Run Code Online (Sandbox Code Playgroud)

2.利用combineLatest

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

navigation.subscribe((navigation) => { ... });
Run Code Online (Sandbox Code Playgroud)