feat(router): set router-link-active when RouterLink is active

Closes #8376
This commit is contained in:
vsavkin 2016-05-01 17:07:10 -07:00 committed by Victor Savkin
parent ec4ca0eace
commit 4fe0f1fa65
4 changed files with 31 additions and 8 deletions

View File

@ -26,6 +26,7 @@ export class RouterLink implements OnDestroy {
private _subscription: any;
@HostBinding() private href: string;
@HostBinding('class.router-link-active') private isActive: boolean = false;
constructor(@Optional() private _routeSegment: RouteSegment, private _router: Router) {
this._subscription =
@ -53,6 +54,9 @@ export class RouterLink implements OnDestroy {
let tree = this._router.createUrlTree(this._changes, this._routeSegment);
if (isPresent(tree)) {
this.href = this._router.serializeUrl(tree);
this.isActive = this._router.urlTree.contains(tree);
} else {
this.isActive = false;
}
}
}

View File

@ -27,9 +27,7 @@ export class Tree<T> {
pathFromRoot(t: T): T[] { return _findPath(t, this._root, []).map(s => s.value); }
contains(tree: Tree<T>): boolean {
return _contains(this._root, tree._root);
}
contains(tree: Tree<T>): boolean { return _contains(this._root, tree._root); }
}
export class UrlTree extends Tree<UrlSegment> {
@ -59,7 +57,7 @@ function _findPath<T>(expected: T, c: TreeNode<T>, collected: TreeNode<T>[]): Tr
collected.push(c);
// TODO: vsavkin remove it once recognize is fixed
if(_equalValues(expected, c.value)) return collected;
if (_equalValues(expected, c.value)) return collected;
for (let cc of c.children) {
let r = _findPath(expected, cc, ListWrapper.clone(collected));
@ -81,9 +79,9 @@ function _contains<T>(tree: TreeNode<T>, subtree: TreeNode<T>): boolean {
return true;
}
function _equalValues(a:any, b:any):boolean {
function _equalValues(a: any, b: any): boolean {
if (a instanceof RouteSegment) return equalSegments(<any>a, <any>b);
if (a instanceof UrlSegment) return equalUrlSegments(<any>a, <any>b)
if (a instanceof UrlSegment) return equalUrlSegments(<any>a, <any>b);
return a === b;
}
@ -156,6 +154,7 @@ export function equalSegments(a: RouteSegment, b: RouteSegment): boolean {
export function equalUrlSegments(a: UrlSegment, b: UrlSegment): boolean {
if (isBlank(a) && !isBlank(b)) return false;
if (!isBlank(a) && isBlank(b)) return false;
if (a.segment != b.segment) return false;
if (a.outlet != b.outlet) return false;
if (isBlank(a.parameters) && !isBlank(b.parameters)) return false;
if (!isBlank(a.parameters) && isBlank(b.parameters)) return false;

View File

@ -192,6 +192,24 @@ export function main() {
.toHaveText('team 22 { relativelink { simple }, aux: }');
})));
it("should set the router-link-active class",
fakeAsync(inject([Router, TestComponentBuilder], (router, tcb) => {
let fixture = tcb.createFakeAsync(RootCmp);
advance(fixture);
router.navigateByUrl('/team/22/relativelink');
advance(fixture);
expect(fixture.debugElement.nativeElement)
.toHaveText('team 22 { relativelink { }, aux: }');
let link = DOM.querySelector(fixture.debugElement.nativeElement, "a");
expect(DOM.hasClass(link, "router-link-active")).toEqual(false);
DOM.dispatchEvent(link, DOM.createMouseEvent('click'));
advance(fixture);
expect(DOM.hasClass(link, "router-link-active")).toEqual(true);
})));
it("should update router links when router changes",
fakeAsync(inject([Router, TestComponentBuilder], (router, tcb) => {
let fixture = tcb.createFakeAsync(RootCmp);

View File

@ -49,12 +49,14 @@ export function main() {
describe("contains", () => {
it("should work", () => {
let tree = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, []), new TreeNode<number>(3, [])]));
let tree = new Tree<any>(
new TreeNode<number>(1, [new TreeNode<number>(2, []), new TreeNode<number>(3, [])]));
let subtree1 = new Tree<any>(new TreeNode<number>(1, []));
let subtree2 = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, [])]));
let subtree3 = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(3, [])]));
let notSubtree1 = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(4, [])]));
let notSubtree2 = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, [new TreeNode<number>(4, [])])]));
let notSubtree2 = new Tree<any>(
new TreeNode<number>(1, [new TreeNode<number>(2, [new TreeNode<number>(4, [])])]));
expect(tree.contains(subtree1)).toEqual(true);
expect(tree.contains(subtree2)).toEqual(true);