fix(router): router link active should take all descendants into account
This commit is contained in:
parent
93a4ca652a
commit
8d90a5a4cf
|
@ -59,8 +59,9 @@ import {RouterLink, RouterLinkWithHref} from './router_link';
|
||||||
*/
|
*/
|
||||||
@Directive({selector: '[routerLinkActive]'})
|
@Directive({selector: '[routerLinkActive]'})
|
||||||
export class RouterLinkActive implements OnChanges, OnDestroy, AfterContentInit {
|
export class RouterLinkActive implements OnChanges, OnDestroy, AfterContentInit {
|
||||||
@ContentChildren(RouterLink) links: QueryList<RouterLink>;
|
@ContentChildren(RouterLink, {descendants: true}) links: QueryList<RouterLink>;
|
||||||
@ContentChildren(RouterLinkWithHref) linksWithHrefs: QueryList<RouterLinkWithHref>;
|
@ContentChildren(RouterLinkWithHref, {descendants: true})
|
||||||
|
linksWithHrefs: QueryList<RouterLinkWithHref>;
|
||||||
|
|
||||||
private classes: string[] = [];
|
private classes: string[] = [];
|
||||||
private subscription: Subscription;
|
private subscription: Subscription;
|
||||||
|
|
|
@ -1226,34 +1226,35 @@ describe('Integration', () => {
|
||||||
|
|
||||||
|
|
||||||
it('should set the class on a parent element when the link is active',
|
it('should set the class on a parent element when the link is active',
|
||||||
fakeAsync(inject(
|
fakeAsync(inject(
|
||||||
[Router, TestComponentBuilder, Location],
|
[Router, TestComponentBuilder, Location],
|
||||||
(router: Router, tcb: TestComponentBuilder, location: Location) => {
|
(router: Router, tcb: TestComponentBuilder, location: Location) => {
|
||||||
const fixture = createRoot(tcb, router, RootCmp);
|
const fixture = createRoot(tcb, router, RootCmp);
|
||||||
|
|
||||||
router.resetConfig([{
|
router.resetConfig([{
|
||||||
path: 'team/:id',
|
path: 'team/:id',
|
||||||
component: TeamCmp,
|
component: TeamCmp,
|
||||||
children: [{
|
children: [{
|
||||||
path: 'link',
|
path: 'link',
|
||||||
component: DummyLinkWithParentCmp,
|
component: DummyLinkWithParentCmp,
|
||||||
children:
|
children: [
|
||||||
[{path: 'simple', component: SimpleCmp}, {path: '', component: BlankCmp}]
|
{path: 'simple', component: SimpleCmp}, {path: '', component: BlankCmp}
|
||||||
}]
|
]
|
||||||
}]);
|
}]
|
||||||
|
}]);
|
||||||
|
|
||||||
router.navigateByUrl('/team/22/link;exact=true');
|
router.navigateByUrl('/team/22/link;exact=true');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(location.path()).toEqual('/team/22/link;exact=true');
|
expect(location.path()).toEqual('/team/22/link;exact=true');
|
||||||
|
|
||||||
const native = fixture.debugElement.nativeElement.querySelector('link-parent');
|
const native = fixture.debugElement.nativeElement.querySelector('link-parent');
|
||||||
expect(native.className).toEqual('active');
|
expect(native.className).toEqual('active');
|
||||||
|
|
||||||
router.navigateByUrl('/team/22/link/simple');
|
router.navigateByUrl('/team/22/link/simple');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(location.path()).toEqual('/team/22/link/simple');
|
expect(location.path()).toEqual('/team/22/link/simple');
|
||||||
expect(native.className).toEqual('');
|
expect(native.className).toEqual('');
|
||||||
})));
|
})));
|
||||||
|
|
||||||
it('should set the class when the link is active',
|
it('should set the class when the link is active',
|
||||||
fakeAsync(inject(
|
fakeAsync(inject(
|
||||||
|
@ -1439,17 +1440,6 @@ class DummyLinkCmp {
|
||||||
constructor(route: ActivatedRoute) { this.exact = (<any>route.snapshot.params).exact === 'true'; }
|
constructor(route: ActivatedRoute) { this.exact = (<any>route.snapshot.params).exact === 'true'; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'link-cmp',
|
|
||||||
template:
|
|
||||||
`<router-outlet></router-outlet><link-parent routerLinkActive="active" [routerLinkActiveOptions]="{exact: exact}"><a [routerLink]="['./']">link</a></link-parent>`,
|
|
||||||
directives: ROUTER_DIRECTIVES
|
|
||||||
})
|
|
||||||
class DummyLinkWithParentCmp {
|
|
||||||
private exact: boolean;
|
|
||||||
constructor(route: ActivatedRoute) { this.exact = (<any>route.snapshot.params).exact === 'true'; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'link-cmp',
|
selector: 'link-cmp',
|
||||||
template: `<a [routerLink]="['../simple']">link</a>`,
|
template: `<a [routerLink]="['../simple']">link</a>`,
|
||||||
|
@ -1566,6 +1556,19 @@ class LinkInNgIf {
|
||||||
alwaysTrue = true;
|
alwaysTrue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'link-cmp',
|
||||||
|
template: `<router-outlet></router-outlet>
|
||||||
|
<link-parent routerLinkActive="active" [routerLinkActiveOptions]="{exact: exact}">
|
||||||
|
<div ngClass="{one: 'true'}"><a [routerLink]="['./']">link</a></div>
|
||||||
|
</link-parent>`,
|
||||||
|
directives: ROUTER_DIRECTIVES
|
||||||
|
})
|
||||||
|
class DummyLinkWithParentCmp {
|
||||||
|
private exact: boolean;
|
||||||
|
constructor(route: ActivatedRoute) { this.exact = (<any>route.snapshot.params).exact === 'true'; }
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'root-cmp',
|
selector: 'root-cmp',
|
||||||
template: `<router-outlet></router-outlet>`,
|
template: `<router-outlet></router-outlet>`,
|
||||||
|
|
Loading…
Reference in New Issue