fix(router): make router links work on non-a tags
This commit is contained in:
@ -54,8 +54,54 @@ import {UrlTree} from '../url_tree';
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
@Directive({selector: '[routerLink]'})
|
||||
export class RouterLink implements OnChanges {
|
||||
@Directive({selector: ':not(a)[routerLink]'})
|
||||
export class RouterLink {
|
||||
@Input() target: string;
|
||||
private commands: any[] = [];
|
||||
@Input() queryParams: {[k: string]: any};
|
||||
@Input() fragment: string;
|
||||
|
||||
urlTree: UrlTree;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(
|
||||
private router: Router, private route: ActivatedRoute,
|
||||
private locationStrategy: LocationStrategy) {}
|
||||
|
||||
@Input()
|
||||
set routerLink(data: any[]|string) {
|
||||
if (Array.isArray(data)) {
|
||||
this.commands = <any>data;
|
||||
} else {
|
||||
this.commands = [data];
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('click', ['$event.button', '$event.ctrlKey', '$event.metaKey'])
|
||||
onClick(button: number, ctrlKey: boolean, metaKey: boolean): boolean {
|
||||
if (button !== 0 || ctrlKey || metaKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof this.target === 'string' && this.target != '_self') {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.router.navigate(
|
||||
this.commands,
|
||||
{relativeTo: this.route, queryParams: this.queryParams, fragment: this.fragment});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link RouterLink} for more information.
|
||||
* @stable
|
||||
*/
|
||||
@Directive({selector: 'a[routerLink]'})
|
||||
export class RouterLinkWithHref implements OnChanges {
|
||||
@Input() target: string;
|
||||
private commands: any[] = [];
|
||||
@Input() queryParams: {[k: string]: any};
|
||||
|
@ -10,9 +10,10 @@ import {AfterContentInit, ContentChildren, Directive, ElementRef, Input, OnChang
|
||||
import {Subscription} from 'rxjs/Subscription';
|
||||
|
||||
import {NavigationEnd, Router} from '../router';
|
||||
import {containsTree} from '../url_tree';
|
||||
import {UrlTree, containsTree} from '../url_tree';
|
||||
|
||||
import {RouterLink, RouterLinkWithHref} from './router_link';
|
||||
|
||||
import {RouterLink} from './router_link';
|
||||
|
||||
/**
|
||||
* The RouterLinkActive directive lets you add a CSS class to an element when the link's route
|
||||
@ -59,6 +60,8 @@ import {RouterLink} from './router_link';
|
||||
@Directive({selector: '[routerLinkActive]'})
|
||||
export class RouterLinkActive implements OnChanges, OnDestroy, AfterContentInit {
|
||||
@ContentChildren(RouterLink) private links: QueryList<RouterLink>;
|
||||
@ContentChildren(RouterLinkWithHref) private linksWithHrefs: QueryList<RouterLinkWithHref>;
|
||||
|
||||
private classes: string[] = [];
|
||||
private subscription: Subscription;
|
||||
|
||||
@ -77,6 +80,7 @@ export class RouterLinkActive implements OnChanges, OnDestroy, AfterContentInit
|
||||
|
||||
ngAfterContentInit(): void {
|
||||
this.links.changes.subscribe(s => this.update());
|
||||
this.linksWithHrefs.changes.subscribe(s => this.update());
|
||||
this.update();
|
||||
}
|
||||
|
||||
@ -93,15 +97,20 @@ export class RouterLinkActive implements OnChanges, OnDestroy, AfterContentInit
|
||||
ngOnDestroy(): any { this.subscription.unsubscribe(); }
|
||||
|
||||
private update(): void {
|
||||
if (!this.links || this.links.length === 0) return;
|
||||
if (!this.links || !this.linksWithHrefs) return;
|
||||
|
||||
const currentUrlTree = this.router.parseUrl(this.router.url);
|
||||
const isActive = this.links.reduce(
|
||||
(res, link) =>
|
||||
const isActiveLinks = this.reduceList(currentUrlTree, this.links);
|
||||
const isActiveLinksWithHrefs = this.reduceList(currentUrlTree, this.linksWithHrefs);
|
||||
this.classes.forEach(
|
||||
c => this.renderer.setElementClass(
|
||||
this.element.nativeElement, c, isActiveLinks || isActiveLinksWithHrefs));
|
||||
}
|
||||
|
||||
private reduceList(currentUrlTree: UrlTree, q: QueryList<any>): boolean {
|
||||
return q.reduce(
|
||||
(res: boolean, link: any) =>
|
||||
res || containsTree(currentUrlTree, link.urlTree, this.routerLinkActiveOptions.exact),
|
||||
false);
|
||||
|
||||
this.classes.forEach(
|
||||
c => this.renderer.setElementClass(this.element.nativeElement, c, isActive));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user