fix(Router) Fix detect active route in depth.

This commit is contained in:
Dmytro Kulyk 2016-04-22 01:43:59 +03:00 committed by Misko Hevery
parent d5f5ce82ca
commit a38c9a1ef7
2 changed files with 68 additions and 16 deletions

View File

@ -4,7 +4,7 @@ import {isBlank, isPresent, Type} from '../src/facade/lang';
import {BaseException} from '../src/facade/exceptions';
import {Location} from '@angular/common';
import {RouteRegistry, ROUTER_PRIMARY_COMPONENT} from './route_registry';
import {ComponentInstruction, Instruction} from './instruction';
import {ComponentInstruction, Instruction, DefaultInstruction} from './instruction';
import {RouterOutlet} from './directives/router_outlet';
import {getCanActivateHook} from './lifecycle/route_lifecycle_reflector';
import {RouteDefinition} from './route_config/route_config_impl';
@ -131,8 +131,9 @@ export class Router {
*/
isRouteActive(instruction: Instruction): boolean {
var router: Router = this;
var currentInstruction = this.currentInstruction;
if (isBlank(this.currentInstruction)) {
if (isBlank(currentInstruction)) {
return false;
}
@ -142,22 +143,28 @@ export class Router {
instruction = instruction.child;
}
if (isBlank(instruction.component) || isBlank(this.currentInstruction.component) ||
this.currentInstruction.component.routeName != instruction.component.routeName) {
return false;
}
let reason = true;
let paramEquals = true;
// check the instructions in depth
do {
if (isBlank(instruction.component) || isBlank(currentInstruction.component) ||
currentInstruction.component.routeName != instruction.component.routeName) {
return false;
}
if (isPresent(instruction.component.params)) {
StringMapWrapper.forEach(instruction.component.params, (value, key) => {
if (currentInstruction.component.params[key] !== value) {
reason = false;
}
});
}
currentInstruction = currentInstruction.child;
instruction = instruction.child;
} while (isPresent(currentInstruction) && isPresent(instruction) &&
!(instruction instanceof DefaultInstruction) && reason);
if (isPresent(this.currentInstruction.component.params)) {
StringMapWrapper.forEach(instruction.component.params, (value, key) => {
if (this.currentInstruction.component.params[key] !== value) {
paramEquals = false;
}
});
}
return paramEquals;
// ignore DefaultInstruction
return reason && (isBlank(instruction) || instruction instanceof DefaultInstruction);
}

View File

@ -295,6 +295,51 @@ export function main() {
router.navigateByUrl('/child-with-grandchild/grandchild?extra=0');
});
}));
it('should not be added to links in other child routes',
inject([AsyncTestCompleter], (async) => {
router.config([
new Route({path: '/child', component: HelloCmp, name: 'Child'}),
new Route({
path: '/child-with-grandchild/...',
component: ParentCmp,
name: 'ChildWithGrandchild'
}),
new Route({
path: '/child-with-other-grandchild/...',
component: ParentCmp,
name: 'ChildWithOtherGrandchild'
})
])
.then((_) => compile(`<a [routerLink]="['./Child']" class="child-link">Child</a>
<a [routerLink]="['./ChildWithGrandchild/Grandchild']" class="child-with-grandchild-link">Better Child</a>
<a [routerLink]="['./ChildWithOtherGrandchild/Grandchild']" class="child-with-other-grandchild-link">Better Child</a>
<router-outlet></router-outlet>`))
.then((_) => {
var element = fixture.debugElement.nativeElement;
fixture.detectChanges();
var link1 = getDOM().querySelector(element, '.child-link');
var link2 = getDOM().querySelector(element, '.child-with-grandchild-link');
var link3 = getDOM().querySelector(element, '.child-with-other-grandchild-link');
expect(link1).not.toHaveCssClass('router-link-active');
expect(link2).not.toHaveCssClass('router-link-active');
expect(link3).not.toHaveCssClass('router-link-active');
router.subscribe((_) => {
fixture.detectChanges();
expect(link1).not.toHaveCssClass('router-link-active');
expect(link2).toHaveCssClass('router-link-active');
expect(link3).not.toHaveCssClass('router-link-active');
async.done();
});
router.navigateByUrl('/child-with-grandchild/grandchild?extra=0');
});
}));
});
describe('when clicked', () => {