我已设置以下路由系统
export const MyRoutes: Routes = [
{path: '', redirectTo: 'new', pathMatch: 'full'},
{path: ':type', component: MyComponent}
];
并拥有以下导航系统
goToPage('new');
goToPageNo('new', 2);
goToPage(type) {
this.router.navigate([type]);
}
goToPageNo(type, pageNo) {
this.router.navigate([type], {queryParams: {page: pageNo}});
}
示例网址看起来像这样
有时他们有可选 queryParams (页面)
现在我需要阅读 route params和queryParams
ngOnInit(): void {
this.paramsSubscription = this.route.params.subscribe((param: any) => {
this.type = param['type'];
this.querySubscription = this.route.queryParams.subscribe((queryParam: any) => {
this.page = queryParam['page'];
if (this.page)
this.goToPageNo(this.type, this.page);
else
this.goToPage(this.type);
});
});
}
ngOnDestroy(): void {
this.paramsSubscription.unsubscribe();
this.querySubscription.unsubscribe();
}
现在这没有按预期工作,访问没有queryParams的页面,然后我访问一个查询参数页面" goToPageNo"多次调用,因为我在route params中订阅了queryParams。
我查看了Angular 2文档,他们没有任何示例或代码同时实现对路由参数和queryParams 的订阅。
有什么方法可以做到这一点吗?有什么建议吗?
答案 0 :(得分:42)
我通过在订阅前使用Observable.combineLatest
组合observable来设法获得queryParams和Params的单一订阅。
例如
var obsComb = Observable.combineLatest(this.route.params, this.route.queryParams,
(params, qparams) => ({ params, qparams }));
obsComb.subscribe( ap => {
console.log(ap.params['type']);
console.log(ap.qparams['page']);
});
答案 1 :(得分:12)
对于Angular 6 +
import { combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
...
combineLatest(this.route.params, this.route.queryParams)
.pipe(map(results => ({params: results[0].xxx, query: results[1]})))
.subscribe(results => {
console.log(results);
});
xxx
来自您的路线
{path: 'post/:xxx', component: MyComponent},
答案 2 :(得分:8)
迟到的答案,但另一个解决方案: 我没有订阅params和queryparams,而是订阅了路由器上的NavigationEnd事件。仅触发一次,并且快照上都有params和queryparams :(角度4的示例)
this.router.events.filter(event=>event instanceof NavigationEnd)
.subscribe(event=>{
let yourparameter = this.activatedroute.snapshot.params.yourparameter;
let yourqueryparameter = this.activatedroute.snapshot.queryParams.yourqueryparameter;
});
关于取消订阅:是的,确实路由params,queryParams或导航事件订阅被路由器自动取消订阅,但有一个例外:如果您的路由有子节点,当在子节点之间导航时,不会发生取消订阅。只有当您离开父路线时才会离开!
E.g。我有一个标签作为子路线的情况。在第一个选项卡组件的构造函数中订阅路径参数以检索数据。每次我从第一个选项卡导航到第二个选项卡,然后再添加另一个订阅,从而导致请求数量相乘。
答案 3 :(得分:1)
使用<header>
<img src={nicklogo} class="logo" alt="logo" />
<div class="center">
<ul>
<li>Me</li>
<li>Projects</li>
<li>Skills</li>
</ul>
</div>
</header>
ActivatedRouteSnapshot
ActivatedRoute
界面具有ActivatedRouteSnapshot
和params
属性,您可以同时获取这两个值。
queryParams
编辑:正如OP所述,我们只用这种技术得到参数的初始值。
示例Plunker
答案 4 :(得分:1)
使用combineLatest
提出的解决方案无法正常工作。在第一个路由更改之后,每次param
或queryParam
值更改时,您都会得到一个事件,这意味着当一个更改但另一个没有更改时,您将处于中间状态。
@rekna的解决方案对我来说很有效,除了我的应用程序首次加载时没有收到事件,所以这是我对@rekna的解决方案的修改:
this.routeUpdate(this.activatedRoute.snapshot);
this.routeSubscription = this.router.events
.pipe(filter(event => event instanceof NavigationEnd))
.subscribe(event => this.routeUpdate(this.activatedRoute.snapshot));
routeUpdate
是执行所需参数处理的一种方法。
答案 5 :(得分:1)
Shifatul 的回答扩展到......
import { combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
// ...
combineLatest([this.route.params, this.route.queryParams])
.subscribe(([params, queryParams]) => {
console.log("your route data:", params, queryParams);
});
答案 6 :(得分:0)
我认为您应该使用zip运算符https://www.learnrxjs.io/operators/combination/zip.html
因为如果您使用CombineLatest并更改url参数或查询参数,则可以通过新的查询参数和旧的url参数获得价值。
网址,例如:
答案 7 :(得分:0)
另一种方法(在Angular 7及更高版本上)是订阅可观察到的ActivatedRoute网址,并使用“ withLatestFrom”获取最新的paramsMap和queryParamsMap。似乎已在可观察到的url发出之前设置了参数:
this.route.url.pipe(
withLatestFrom(this.route.paramMap, this.route.queryParamMap)
).subscribe(([url, paramMap, queryParamMap]) => {
// Do something with url, paramsMap and queryParamsMap
});
https://rxjs-dev.firebaseapp.com/api/operators/withLatestFrom
答案 8 :(得分:0)
按照 Shifatul 的回答,这假设对 observables 的工作同时改变并且只触发一次:
import { combineLatest } from 'rxjs';
import { map, debounceTime } from 'rxjs/operators';
...
combineLatest(this.route.params, this.route.queryParams)
.pipe(map(results => ({params: results[0].xxx, query: results[1]})), debounceTime(0))
.subscribe(results => {
console.log(results);
});