feat(router): export routerLinkActive w/ isActive property

This commit is contained in:
Jeremy Elbourn 2016-10-25 12:51:24 -07:00 committed by vsavkin
parent 6ccbfd41dd
commit c9f58cf78c
3 changed files with 60 additions and 5 deletions

View File

@ -52,6 +52,14 @@ import {RouterLink, RouterLinkWithHref} from './router_link';
* true}">Bob</a>
* ```
*
* You can assign the RouterLinkActive instance to a template variable and directly check
* the `isActive` status.
* ```
* <a routerLink="/user/bob" routerLinkActive #rla="routerLinkActive">
* Bob {{ rla.isActive ? '(already open)' : ''}}
* </a>
* ```
*
* Finally, you can apply the RouterLinkActive directive to an ancestor of a RouterLink.
*
* ```
@ -69,8 +77,12 @@ import {RouterLink, RouterLinkWithHref} from './router_link';
*
* @stable
*/
@Directive({selector: '[routerLinkActive]'})
export class RouterLinkActive implements OnChanges, OnDestroy, AfterContentInit {
@Directive({
selector: '[routerLinkActive]',
exportAs: 'routerLinkActive',
})
export class RouterLinkActive implements OnChanges,
OnDestroy, AfterContentInit {
@ContentChildren(RouterLink, {descendants: true}) links: QueryList<RouterLink>;
@ContentChildren(RouterLinkWithHref, {descendants: true})
linksWithHrefs: QueryList<RouterLinkWithHref>;
@ -88,6 +100,8 @@ export class RouterLinkActive implements OnChanges, OnDestroy, AfterContentInit
});
}
get isActive(): boolean { return this.hasActiveLink(); }
ngAfterContentInit(): void {
this.links.changes.subscribe(s => this.update());
this.linksWithHrefs.changes.subscribe(s => this.update());
@ -110,8 +124,11 @@ export class RouterLinkActive implements OnChanges, OnDestroy, AfterContentInit
if (!this.links || !this.linksWithHrefs || !this.router.navigated) return;
const isActive = this.hasActiveLink();
this.classes.forEach(
c => this.renderer.setElementClass(this.element.nativeElement, c, isActive));
this.classes.forEach(c => {
if (c) {
this.renderer.setElementClass(this.element.nativeElement, c, isActive);
}
});
}
private isLinkActive(router: Router): (link: (RouterLink|RouterLinkWithHref)) => boolean {

View File

@ -1638,6 +1638,43 @@ describe('Integration', () => {
expect(native.className).toEqual('active');
})));
it('should expose an isActive property', fakeAsync(() => {
@Component({
template: `<a routerLink="/team" routerLinkActive #rla="routerLinkActive"></a>
<p>{{rla.isActive}}</p>
<router-outlet></router-outlet>`
})
class ComponentWithRouterLink {
}
TestBed.configureTestingModule({declarations: [ComponentWithRouterLink]});
const router: Router = TestBed.get(Router);
router.resetConfig([
{
path: 'team',
component: TeamCmp,
},
{
path: 'otherteam',
component: TeamCmp,
}
]);
const f = TestBed.createComponent(ComponentWithRouterLink);
router.navigateByUrl('/team');
advance(f);
const paragraph = f.nativeElement.querySelector('p');
expect(paragraph.textContent).toEqual('true');
router.navigateByUrl('/otherteam');
advance(f);
expect(paragraph.textContent).toEqual('false');
}));
});
describe('lazy loading', () => {
@ -2338,4 +2375,4 @@ function createRoot(router: Router, type: any): ComponentFixture<any> {
]
})
class TestModule {
}
}

View File

@ -233,6 +233,7 @@ export declare class RouterLink {
/** @stable */
export declare class RouterLinkActive implements OnChanges, OnDestroy, AfterContentInit {
isActive: boolean;
links: QueryList<RouterLink>;
linksWithHrefs: QueryList<RouterLinkWithHref>;
routerLinkActive: string[] | string;