feat(router): set router-link-active when RouterLink is active
Closes #8376
This commit is contained in:
parent
ec4ca0eace
commit
4fe0f1fa65
|
@ -26,6 +26,7 @@ export class RouterLink implements OnDestroy {
|
||||||
private _subscription: any;
|
private _subscription: any;
|
||||||
|
|
||||||
@HostBinding() private href: string;
|
@HostBinding() private href: string;
|
||||||
|
@HostBinding('class.router-link-active') private isActive: boolean = false;
|
||||||
|
|
||||||
constructor(@Optional() private _routeSegment: RouteSegment, private _router: Router) {
|
constructor(@Optional() private _routeSegment: RouteSegment, private _router: Router) {
|
||||||
this._subscription =
|
this._subscription =
|
||||||
|
@ -53,6 +54,9 @@ export class RouterLink implements OnDestroy {
|
||||||
let tree = this._router.createUrlTree(this._changes, this._routeSegment);
|
let tree = this._router.createUrlTree(this._changes, this._routeSegment);
|
||||||
if (isPresent(tree)) {
|
if (isPresent(tree)) {
|
||||||
this.href = this._router.serializeUrl(tree);
|
this.href = this._router.serializeUrl(tree);
|
||||||
|
this.isActive = this._router.urlTree.contains(tree);
|
||||||
|
} else {
|
||||||
|
this.isActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,9 +27,7 @@ export class Tree<T> {
|
||||||
|
|
||||||
pathFromRoot(t: T): T[] { return _findPath(t, this._root, []).map(s => s.value); }
|
pathFromRoot(t: T): T[] { return _findPath(t, this._root, []).map(s => s.value); }
|
||||||
|
|
||||||
contains(tree: Tree<T>): boolean {
|
contains(tree: Tree<T>): boolean { return _contains(this._root, tree._root); }
|
||||||
return _contains(this._root, tree._root);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UrlTree extends Tree<UrlSegment> {
|
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);
|
collected.push(c);
|
||||||
|
|
||||||
// TODO: vsavkin remove it once recognize is fixed
|
// 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) {
|
for (let cc of c.children) {
|
||||||
let r = _findPath(expected, cc, ListWrapper.clone(collected));
|
let r = _findPath(expected, cc, ListWrapper.clone(collected));
|
||||||
|
@ -81,9 +79,9 @@ function _contains<T>(tree: TreeNode<T>, subtree: TreeNode<T>): boolean {
|
||||||
return true;
|
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 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;
|
return a === b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +154,7 @@ export function equalSegments(a: RouteSegment, b: RouteSegment): boolean {
|
||||||
export function equalUrlSegments(a: UrlSegment, b: UrlSegment): boolean {
|
export function equalUrlSegments(a: UrlSegment, b: UrlSegment): boolean {
|
||||||
if (isBlank(a) && !isBlank(b)) return false;
|
if (isBlank(a) && !isBlank(b)) return false;
|
||||||
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 (a.outlet != b.outlet) return false;
|
||||||
if (isBlank(a.parameters) && !isBlank(b.parameters)) return false;
|
if (isBlank(a.parameters) && !isBlank(b.parameters)) return false;
|
||||||
if (!isBlank(a.parameters) && isBlank(b.parameters)) return false;
|
if (!isBlank(a.parameters) && isBlank(b.parameters)) return false;
|
||||||
|
|
|
@ -192,6 +192,24 @@ export function main() {
|
||||||
.toHaveText('team 22 { relativelink { simple }, aux: }');
|
.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",
|
it("should update router links when router changes",
|
||||||
fakeAsync(inject([Router, TestComponentBuilder], (router, tcb) => {
|
fakeAsync(inject([Router, TestComponentBuilder], (router, tcb) => {
|
||||||
let fixture = tcb.createFakeAsync(RootCmp);
|
let fixture = tcb.createFakeAsync(RootCmp);
|
||||||
|
|
|
@ -49,12 +49,14 @@ export function main() {
|
||||||
|
|
||||||
describe("contains", () => {
|
describe("contains", () => {
|
||||||
it("should work", () => {
|
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 subtree1 = new Tree<any>(new TreeNode<number>(1, []));
|
||||||
let subtree2 = new Tree<any>(new TreeNode<number>(1, [new TreeNode<number>(2, [])]));
|
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 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 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(subtree1)).toEqual(true);
|
||||||
expect(tree.contains(subtree2)).toEqual(true);
|
expect(tree.contains(subtree2)).toEqual(true);
|
||||||
|
|
Loading…
Reference in New Issue