Angular2路由器保留查询字符串
我编写了一个利用路由器的Angular2(v2.0.1)应用程序。网站加载了多个查询字符串参数,因此完整URL最初如下所示:Angular2路由器保留查询字符串,angular,angular2-routing,Angular,Angular2 Routing,我编写了一个利用路由器的Angular2(v2.0.1)应用程序。网站加载了多个查询字符串参数,因此完整URL最初如下所示: https://my.application.com/?param1=val1¶m2=val2¶m3=val3 https://my.application.com/comp1 在我的路由配置中,我有一个重定向空路由的条目: const appRoutes: Routes = [ { path: '',
https://my.application.com/?param1=val1¶m2=val2¶m3=val3
https://my.application.com/comp1
在我的路由配置中,我有一个重定向空路由的条目:
const appRoutes: Routes = [
{
path: '',
redirectTo: '/comp1',
pathMatch: 'full'
},
{
path: 'comp1',
component: FirstComponent
},
{
path: 'comp2',
component: SecondComponent
}
];
我的问题是,应用程序启动后,URL不再包含查询参数,而是如下所示:
https://my.application.com/?param1=val1¶m2=val2¶m3=val3
https://my.application.com/comp1
是否有任何方法可以配置路由器,使其在导航时保留初始查询字符串
谢谢你Lukas您可能希望搜索类似于此的功能请求。如果不存在,请提交功能请求
同时:我相信您需要在路径“”上创建一个组件,唯一的目的是在保留QueryString参数的同时重定向到“/comp1” 我认为没有办法在路由配置中定义这一点 目前它支持
routerLink
s和命令式导航来启用
- 及
/comp1
路由的防护导航完成
router.navigate(['/comp1'], { preserveQueryParams: true }); //deprecated. see update note
存在允许全局配置preserveQueryParams
的选项
更新说明:from,preserveQueryParams已被弃用,请改用queryParamsHandlingGünter Zöchbauer的答案应该可以正常工作,但由于某些原因,它根本不适合我。最终起作用的是直接传递
queryParams
,而不是“保存”它们
这就是我的守卫的样子:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
(...)
this.router.navigate(['login'], { queryParams: route.queryParams });
}
在-base href中捕获原始url- 然后它就会出现
如果使用HTML模板导航,则可以使用
<a [routerLink]="['/page-2']" [routerLinkActive]="['is-active']" queryParamsHandling="merge">
需要注意的是queryParamsHandling param没有方括号。如果使用HTML模板导航,也可以使用
preserveQueryParams=“true”
请注意,preserveQueryParams
没有方括号
例如:
有一种解决方法,使用辅助路线,因为它们将在主路线导航中保持这些路线
首先,在顶部组件中添加一个命名路由器插座:
<router-outlet name="params"><router-outlet>
并定义将此组件实例化到命名出口的路由:
{
path: ':val1',
component: ParamsComponent,
outlet: "params"
}
将应用程序导航更改为:
如果查看任何ActivatedRoute,可以使用以下方法找到“params”路由:
var paramsRoute = this.activatedRoute.route.children.find(r => r.outlet == "params");
如果paramsRoute为null,则url不包含(params:val1)
下一部分变得有点“粗糙”,因为在初始加载的主路由之后实例化了次路由。因此,在应用程序完全加载之前,您可能会发现paramsRoute.snapshot为null。有一个私有属性“_futureSnapshot”,它将在初始启动时包含路由参数…并在应用程序的整个生命周期中保持不变。您可以通过以下方式获得这些信息:
var queryParams =
paramsRoute
? paramsRoute["_futureSnapshot"].params
: {};
var val1 = queryParams["val1"];
鉴于futureSnapshot不是公共API的一部分,这可能是我们不应该使用的字段。如果您觉得使用它不方便,您可能会订阅paramsRoute.params,但这可能会使您的组件复杂化
if (paramsRoute) {
paramsRoute.params.subscribe(params => {
this.queryParams = params;
this.loadData();
});
} else {
this.queryParams = {};
this.loadData();
}
=========修正案=============
我找到了一个更好的方法来提取查询参数,这绝对不是令人讨厌的。。。在路由发生前实例化的组件或服务中,添加以下逻辑:
const routeRecognizedSubscription = this.router.events
.filter(e => e instanceof RoutesRecognized)
.subscribe((e: RoutesRecognized) => {
const paramsRoute = e.state.root.children.find(r => r.outlet == "params");
if (paramsRoute) {
// capture or use paramsRoute.params
}
routeRecognizedSubscription.unsubscribe();
});
此代码临时订阅在导航之前发生的RoutesRecognited事件。在收到第一个事件后,它将自动取消订阅,因为我们只需要在应用程序启动时执行此操作
在第一个事件中,我们查找对应于“params”outlet的状态。如果找到,params属性将包含我们需要的数据。无需访问私有属性。事实证明,在没有其他黑客攻击的情况下,无文档记录的方法就是删除“redirectTo”字段中的前导斜杠。由于您正在匹配完整路径,因此可以确定它将执行您想要的操作(即,没有意外的url段),并且由于它不再是绝对目标,Angular将保留当前查询参数 所以在这种情况下
{
path: '',
redirectTo: '/comp1',
pathMatch: 'full'
}
变成:
{
path: '',
redirectTo: 'comp1',
pathMatch: 'full'
}
资料来源:在尝试了最多的答案后,我发现
- 甘特·泽克鲍尔的回答对我根本不起作用
- 克里斯托弗建议删除前导的
也没有起作用/
- AArias的回答确实有效,但导致历史上增加了两个URL:
在Angular 10中,现在您可以按如下方式使用:https://my.application.com/comp1?param=val
谢谢,我会查看这些问题,并在必要时提交一份。这行代码将添加到哪里?你能用一个代码示例来解释“guard”吗?我这样做了,但是在空字符串“redirect”路由中添加一个canActivate guard并没有被选中。好的,但问题仍然存在于应用程序条目中。如果你试图在应用程序启动后“捕获”url参数,那就太晚了。它们已经被剥光了。过了很长时间,我发现从'@angular/Router'导入{ActivatedRoute,Router}; 类组件{ 构造函数(专用路由:ActivatedRoute,专用路由器:router){} someMethod(){ //可以使用“合并”或“保留”来保留查询参数 this.router.navigate(['/'],{queryParamsHandling:'preserve'}) } }
不起作用。最好总是使用navigateByUrl
。很抱歉我投了反对票,但只有AArias的答案对我有效(Angular 9,如果相关的话)。这似乎不是一个答案。这是最好的答案,关于括号的注释确实节省了我一些时间。HTML解决方案才是我真正想要的。谢谢您可以使用方括号:[queryParamsHandling]=“'merge'”这是角度的基本概念,括号表示“需要计算”,因此相反导航