diff --git a/modules/@angular/router/src/create_url_tree.ts b/modules/@angular/router/src/create_url_tree.ts index d99dc4774b..9bf41b5427 100644 --- a/modules/@angular/router/src/create_url_tree.ts +++ b/modules/@angular/router/src/create_url_tree.ts @@ -182,6 +182,7 @@ function createPositionApplyingDoubleDots( } function getPath(command: any): any { + if (typeof command === 'object' && command.outlets) return command.outlets[PRIMARY_OUTLET]; return `${command}`; } @@ -201,9 +202,13 @@ function updateSegmentGroup( } const m = prefixedWith(segmentGroup, startIndex, commands); - const slicedCommands = commands.slice(m.lastIndex); - - if (m.match && slicedCommands.length === 0) { + const slicedCommands = commands.slice(m.commandIndex); + if (m.match && m.pathIndex < segmentGroup.segments.length) { + var g = new UrlSegmentGroup(segmentGroup.segments.slice(0, m.pathIndex), {}); + g.children[PRIMARY_OUTLET] = + new UrlSegmentGroup(segmentGroup.segments.slice(m.pathIndex), segmentGroup.children); + return updateSegmentGroupChildren(g, 0, slicedCommands); + } else if (m.match && slicedCommands.length === 0) { return new UrlSegmentGroup(segmentGroup.segments, {}); } else if (m.match && !segmentGroup.hasChildren()) { return createNewSegmentGroup(segmentGroup, startIndex, commands); @@ -241,7 +246,7 @@ function prefixedWith(segmentGroup: UrlSegmentGroup, startIndex: number, command let currentCommandIndex = 0; let currentPathIndex = startIndex; - const noMatch = {match: false, lastIndex: 0}; + const noMatch = {match: false, pathIndex: 0, commandIndex: 0}; while (currentPathIndex < segmentGroup.segments.length) { if (currentCommandIndex >= commands.length) return noMatch; const path = segmentGroup.segments[currentPathIndex]; @@ -249,6 +254,8 @@ function prefixedWith(segmentGroup: UrlSegmentGroup, startIndex: number, command const next = currentCommandIndex < commands.length - 1 ? commands[currentCommandIndex + 1] : null; + if (currentPathIndex > 0 && curr === undefined) break; + if (curr && next && (typeof next === 'object') && next.outlets === undefined) { if (!compare(curr, next, path)) return noMatch; currentCommandIndex += 2; @@ -259,7 +266,7 @@ function prefixedWith(segmentGroup: UrlSegmentGroup, startIndex: number, command currentPathIndex++; } - return {match: true, lastIndex: currentCommandIndex}; + return {match: true, pathIndex: currentPathIndex, commandIndex: currentCommandIndex}; } function createNewSegmentGroup( diff --git a/modules/@angular/router/test/integration.spec.ts b/modules/@angular/router/test/integration.spec.ts index 1bada30713..0ddbd228c6 100644 --- a/modules/@angular/router/test/integration.spec.ts +++ b/modules/@angular/router/test/integration.spec.ts @@ -264,6 +264,27 @@ describe('Integration', () => { expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: simple ]'); }))); + it('should support secondary routes in seperate commands', + fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); + + router.resetConfig([{ + path: 'team/:id', + component: TeamCmp, + children: [ + {path: 'user/:name', component: UserCmp}, + {path: 'simple', component: SimpleCmp, outlet: 'right'} + ] + }]); + + router.navigateByUrl('/team/22/user/victor'); + advance(fixture); + router.navigate(['team/22', {outlets: {right: 'simple'}}]); + advance(fixture); + + expect(fixture.nativeElement).toHaveText('team 22 [ user victor, right: simple ]'); + }))); + it('should deactivate outlets', fakeAsync(inject([Router], (router: Router) => { const fixture = createRoot(router, RootCmp);