Angular - routerLinkActive 和 queryParams 处理 [英] Angular - routerLinkActive and queryParams handling
问题描述
2021 年 3 月更新
Angular 团队最终为此合并了 PR,您可以查看 https://github.com/angular/angular/pull/40303 了解更多详情.
要使用它,只需输入
其中 options
将具有 IsActiveMatchOptions 的形状
export 声明接口 IsActiveMatchOptions {片段:'精确' |'忽略';矩阵参数:'精确' |'子集' |'忽略';路径:'精确' |'子集';查询参数:'精确' |'子集' |'忽略';}
或者简单地接受一个布尔值 exact
<代码>{精确:布尔值}
原始问题
我在 Angular 中使用 routerLink 如下
<a [routerLink]="['/view', 10]";[queryParams]="{'offset': 0, 'numberOfItems': 100}";queryParamsHandling=合并"><div>视图</div><div><span class="badge";[innerHtml]=viewCount"></span></div></a>
所以当 URL 看起来像这样 .active 类被添加到 li 标签
/view/10?offset=0&numberOfItems=100
如果 URL 被更改为 offset
或 numberOfItems
为不同的值,.active 类将被删除,例如.
/view/10?offset=0&numberOfItems=120
我浏览了 angular docs 并设法通过添加另一个 routerLink 使其工作,但是将其隐藏如下.
<a [routerLink]="['/view', 10]";[queryParams]="{'offset': 0, 'numberOfItems': 100}";queryParamsHandling=合并"><div>视图</div><div><span class="badge";[innerHtml]=viewCount"></span></div></a><a [routerLink]="['/view', 10]";样式=显示:无;"><div><span class="badge";[innerHtml]=viewCount"></span></div></a>
似乎上述方法有点小技巧.当路由器参数带有可选查询参数时,是否可以设置任何配置以使 routerLinkActive 工作?
您可能会发现这很有帮助 - 扩展 RouterLinkActive - 如果项目包含字符串,则它被选中"...
import { Directive, Input, OnChanges, ElementRef, Renderer2, ChangeDetectorRef, SimpleChanges, Injector, AfterContentInit } from '@angular/core';import { Router,RouterLinkActive, RouterLink, RouterLinkWithHref } from '@angular/router';@指示({选择器:'[routerLinkActiveQS]',exportAs: 'routerLinkActiveQS'})导出类 RouterLinkQsactiveDirective 扩展 RouterLinkActive 实现 OnChanges、AfterContentInit{@输入()设置 routerLinkActiveQS(data: string[]|string) {(<any>this).routerLinkActive = 数据;}@Input() routerLinkActiveQSContains :字符串;构造函数(注入器:注入器){超级 (injector.get(Router),injector.get(ElementRef),injector.get(Renderer2),injector.get(ChangeDetectorRef));(RouterLinkQsactiveDirective.prototype).isLinkActive = this.MyisLinkActive;}ngOnChanges(changes: SimpleChanges): void {super.ngOnChanges(changes);}ngAfterContentInit(): 无效 {super.ngAfterContentInit();}private MyisLinkActive(router: Router): (link: (RouterLink|RouterLinkWithHref)) =>布尔{const 结果 = (链接:RouterLink | RouterLinkWithHref) =>{让 resultInsde = router.isActive(link.urlTree, this.routerLinkActiveOptions.exact);resultInsde = resultInsde ||router.url.includes ( this.routerLinkActiveQSContains );返回结果插入;}返回结果;}}
Update March 2021
Angular team finally merge the PR for that, you can looks at https://github.com/angular/angular/pull/40303 for more detail.
To use it, simply put
<div routerLinkActive="active-link" [routerLinkActiveOptions]="options">
</div>
Where options
will have the either the shape of IsActiveMatchOptions
export declare interface IsActiveMatchOptions {
fragment: 'exact' | 'ignored';
matrixParams: 'exact' | 'subset' | 'ignored';
paths: 'exact' | 'subset';
queryParams: 'exact' | 'subset' | 'ignored';
}
or simply accept a boolean exact
{
exact: boolean
}
Original Question
I am using routerLink in Angular as below
<li routerLinkActive="active">
<a [routerLink]="['/view', 10]"
[queryParams]="{'offset': 0, 'numberOfItems': 100}"
queryParamsHandling="merge">
<div>View</div>
<div><span class="badge" [innerHtml]="viewCount"></span></div>
</a>
</li>
So the .active class was added to li tag when the URL looks like
/view/10?offset=0&numberOfItems=100
If the URL was changed either offset
or numberOfItems
to a different value, the .active class will be removed, such as.
/view/10?offset=0&numberOfItems=120
I went through the angular docs and managed to make it works by adding another routerLink but make it hidden as below.
<li routerLinkActive="active">
<a [routerLink]="['/view', 10]"
[queryParams]="{'offset': 0, 'numberOfItems': 100}"
queryParamsHandling="merge">
<div>View</div>
<div><span class="badge" [innerHtml]="viewCount"></span></div>
</a>
<a [routerLink]="['/view', 10]" style="display:none;">
<div><span class="badge" [innerHtml]="viewCount"></span></div>
</a>
</li>
Seem the above approach is a little hack. Is there any configuration that I can set to make routerLinkActive works when router parameter presents with optional query parameter?
You may find this helpful - extend RouterLinkActive - an item is 'selected' if it contains a string...
import { Directive, Input, OnChanges, ElementRef, Renderer2, ChangeDetectorRef, SimpleChanges, Injector, AfterContentInit } from '@angular/core';
import { Router,RouterLinkActive, RouterLink, RouterLinkWithHref } from '@angular/router';
@Directive({
selector: '[routerLinkActiveQS]',
exportAs: 'routerLinkActiveQS'
})
export class RouterLinkQsactiveDirective extends RouterLinkActive implements OnChanges, AfterContentInit
{
@Input()
set routerLinkActiveQS(data: string[]|string) {
(<any>this).routerLinkActive = data;
}
@Input() routerLinkActiveQSContains : string;
constructor ( injector: Injector ) {
super ( injector.get(Router),injector.get(ElementRef),injector.get(Renderer2),injector.get(ChangeDetectorRef));
(<any>RouterLinkQsactiveDirective.prototype).isLinkActive = this.MyisLinkActive;
}
ngOnChanges(changes: SimpleChanges): void {
super.ngOnChanges(changes);
}
ngAfterContentInit(): void {
super.ngAfterContentInit();
}
private MyisLinkActive(router: Router): (link: (RouterLink|RouterLinkWithHref)) => boolean {
const result = (link: RouterLink | RouterLinkWithHref) => {
let resultInsde = router.isActive(link.urlTree, this.routerLinkActiveOptions.exact);
resultInsde = resultInsde || router.url.includes ( this.routerLinkActiveQSContains );
return resultInsde;
}
return result;
}
}
这篇关于Angular - routerLinkActive 和 queryParams 处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!