在 Angular 应用程序中通过 RouterLink 处理动态 URL 参数
Handling Dynamic URL Params via RouterLink in Angular App
在我的 Angular 2 应用程序中,我有一个选项卡区域,用户可以在其中 select 来自一组独立但上下文相关的组件。当他们单击这些链接之一时,相关组件会根据 routerLink 中定义的内容加载,如下所示:
<a class="page-content-header-item" routerLink="/page1" routerLinkActive="selected">Page 1</a>
效果很好。但是,从那时起,我们构建了应用程序以将各种用户select编辑的过滤器select离子保存为URL中的参数。这样,当他们重新加载组件时,他们最新的 selection 仍然可见并应用于数据。所以 URL 在用户做了一些过滤器后可能看起来像这样 selections:
http://somesite.com/page1;language_filter=true;language_selection=English
它的组件代码如下所示:
public changePage(page, value, type, body)
{
this.onUserSelection(value, type, body, page);
this.route.params.subscribe(
(params: any) => {
this.page = params['page'];
this.language_filter = params['language_filter'];
this.language_selection = params['language_selection'];
}
);
this.router.navigate(
['/page1', {
page: page,
language_filter: this.language_filter,
language_selection: this.language_selection,
}]);
}
这适用于通过路由文件完成的主要导航方法,其中每个方法如下所示:
{ path: 'page1', component: Page1Component, canActivate: [AuthGuard], data: {contentId: 'page1'} }
但是,对于我提到的这个选项卡区域,它是根据硬编码的 routerLink 参数加载组件。所以我现在意识到,当用户以这种方式返回组件时,而不是通过我们提供的其他方式之一,它实际上会覆盖 URL 参数 - 因为它实际上是在加载 "page1" - - 因为这个 <a class="page-content-header-item" routerLink="/page1" routerLinkActive="selected">Page 1</a>
... 因此之前添加的 URL 参数被清除。
所以,我的问题是,有什么方法可以编辑这段代码:
<a class="page-content-header-item" routerLink="/page1" routerLinkActive="selected">Page 1</a>
...所以它允许一些动态变量?还是我必须找到一种新方法来处理此选项卡区域中的导航?
这是我使用 queryParams
.
得出的解决方案
首先,您可以使用 queryParams
指令在 routerLink
指令中传递参数:
<a routerLink="/page1" [queryParams]="fooParams">Page 1</a>
<a routerLink="/page2">Page 2</a>
<router-outlet></router-outlet>
其中 fooParams
是普通对象:
export class MainComponent {
fooParams = {
language_filter: true,
language_selection: 'english'
}
}
Angular 会像
一样输出这个 url
href="localhost:4200/page1?language_filter=true&language_selection=english"
接下来你要做的是设置一种拦截 ActivatedRoute
的方法,这样你就可以从 ActivatedRouteSnapshot
中提取参数的值。您可以使用解析器或直接在您的组件中执行此操作。在我的示例中,我使用了解析器:
@Injectable()
export class RoutingResolve implements Resolve<any> {
resolve(routeSnapshot: ActivatedRouteSnapshot) {
const { language_filter, language_selection } = routeSnapshot.queryParams;
return { language_filter, language_selection };
}
}
然后在路由定义中传递解析器:
const ROUTES: Routes = [
{
path: 'page1',
component: PageOneComponent,
// In this route we define a resolver so we can intercept the
// activatedRoute snapshot before the component is loaded
resolve: {
routing: RoutingResolve
}
},
{
path: 'page2',
component: PageTwoComponent
}
];
然后,在 PageOneComponent
中,您可以订阅已解析的数据并用它做任何您想做的事情,例如,用它设置表单的值并在表单更改时更新 queryParams。
有关完整示例,请查看此 plunker
确保在单独的 window 中打开预览,这样您就可以在浏览器中看到路线变化。
如果您导航到第 1 页,更改表单中的值,然后导航到第 2 页,然后在浏览器中按返回键,您可以看到表单中加载的值对应于 url.
在我的 Angular 2 应用程序中,我有一个选项卡区域,用户可以在其中 select 来自一组独立但上下文相关的组件。当他们单击这些链接之一时,相关组件会根据 routerLink 中定义的内容加载,如下所示:
<a class="page-content-header-item" routerLink="/page1" routerLinkActive="selected">Page 1</a>
效果很好。但是,从那时起,我们构建了应用程序以将各种用户select编辑的过滤器select离子保存为URL中的参数。这样,当他们重新加载组件时,他们最新的 selection 仍然可见并应用于数据。所以 URL 在用户做了一些过滤器后可能看起来像这样 selections:
http://somesite.com/page1;language_filter=true;language_selection=English
它的组件代码如下所示:
public changePage(page, value, type, body)
{
this.onUserSelection(value, type, body, page);
this.route.params.subscribe(
(params: any) => {
this.page = params['page'];
this.language_filter = params['language_filter'];
this.language_selection = params['language_selection'];
}
);
this.router.navigate(
['/page1', {
page: page,
language_filter: this.language_filter,
language_selection: this.language_selection,
}]);
}
这适用于通过路由文件完成的主要导航方法,其中每个方法如下所示:
{ path: 'page1', component: Page1Component, canActivate: [AuthGuard], data: {contentId: 'page1'} }
但是,对于我提到的这个选项卡区域,它是根据硬编码的 routerLink 参数加载组件。所以我现在意识到,当用户以这种方式返回组件时,而不是通过我们提供的其他方式之一,它实际上会覆盖 URL 参数 - 因为它实际上是在加载 "page1" - - 因为这个 <a class="page-content-header-item" routerLink="/page1" routerLinkActive="selected">Page 1</a>
... 因此之前添加的 URL 参数被清除。
所以,我的问题是,有什么方法可以编辑这段代码:
<a class="page-content-header-item" routerLink="/page1" routerLinkActive="selected">Page 1</a>
...所以它允许一些动态变量?还是我必须找到一种新方法来处理此选项卡区域中的导航?
这是我使用 queryParams
.
首先,您可以使用 queryParams
指令在 routerLink
指令中传递参数:
<a routerLink="/page1" [queryParams]="fooParams">Page 1</a>
<a routerLink="/page2">Page 2</a>
<router-outlet></router-outlet>
其中 fooParams
是普通对象:
export class MainComponent {
fooParams = {
language_filter: true,
language_selection: 'english'
}
}
Angular 会像
一样输出这个 urlhref="localhost:4200/page1?language_filter=true&language_selection=english"
接下来你要做的是设置一种拦截 ActivatedRoute
的方法,这样你就可以从 ActivatedRouteSnapshot
中提取参数的值。您可以使用解析器或直接在您的组件中执行此操作。在我的示例中,我使用了解析器:
@Injectable()
export class RoutingResolve implements Resolve<any> {
resolve(routeSnapshot: ActivatedRouteSnapshot) {
const { language_filter, language_selection } = routeSnapshot.queryParams;
return { language_filter, language_selection };
}
}
然后在路由定义中传递解析器:
const ROUTES: Routes = [
{
path: 'page1',
component: PageOneComponent,
// In this route we define a resolver so we can intercept the
// activatedRoute snapshot before the component is loaded
resolve: {
routing: RoutingResolve
}
},
{
path: 'page2',
component: PageTwoComponent
}
];
然后,在 PageOneComponent
中,您可以订阅已解析的数据并用它做任何您想做的事情,例如,用它设置表单的值并在表单更改时更新 queryParams。
有关完整示例,请查看此 plunker
确保在单独的 window 中打开预览,这样您就可以在浏览器中看到路线变化。
如果您导航到第 1 页,更改表单中的值,然后导航到第 2 页,然后在浏览器中按返回键,您可以看到表单中加载的值对应于 url.