diff --git a/modules/@angular/router/src/recognize.ts b/modules/@angular/router/src/recognize.ts index ac95d4e178..4856fd12d9 100644 --- a/modules/@angular/router/src/recognize.ts +++ b/modules/@angular/router/src/recognize.ts @@ -24,8 +24,8 @@ class NoMatch { class InheritedFromParent { constructor( - public parent: InheritedFromParent, public params: Params, public data: Data, - public resolve: InheritedResolve) {} + public parent: InheritedFromParent, public snapshot: ActivatedRouteSnapshot, + public params: Params, public data: Data, public resolve: InheritedResolve) {} get allParams(): Params { return this.parent ? merge(this.parent.allParams, this.params) : this.params; @@ -33,8 +33,8 @@ class InheritedFromParent { get allData(): Data { return this.parent ? merge(this.parent.allData, this.data) : this.data; } - static get empty(): InheritedFromParent { - return new InheritedFromParent(null, {}, {}, new InheritedResolve(null, {})); + static empty(snapshot: ActivatedRouteSnapshot): InheritedFromParent { + return new InheritedFromParent(null, snapshot, {}, {}, new InheritedResolve(null, {})); } } @@ -42,7 +42,7 @@ export function recognize(rootComponentType: Type, config: Routes, urlTree: UrlT Observable { try { const children = - processSegment(config, urlTree.root, InheritedFromParent.empty, PRIMARY_OUTLET); + processSegment(config, urlTree.root, InheritedFromParent.empty(null), PRIMARY_OUTLET); const root = new ActivatedRouteSnapshot( [], {}, {}, PRIMARY_OUTLET, rootComponentType, null, urlTree.root, -1, InheritedResolve.empty); @@ -119,12 +119,10 @@ function processPathsWithParamsAgainstRoute( return [new TreeNode(snapshot, [])]; } - const {consumedPaths, parameters, lastChild} = match(rawSegment, route, paths); + const {consumedPaths, parameters, lastChild} = + match(rawSegment, route, paths, inherited.snapshot); const rawSlicedPath = paths.slice(lastChild); const childConfig = getChildConfig(route); - const newInherited = route.component ? - InheritedFromParent.empty : - new InheritedFromParent(inherited, parameters, getData(route), newInheritedResolve); const {segment, slicedPath} = split(rawSegment, consumedPaths, rawSlicedPath, childConfig); @@ -134,6 +132,10 @@ function processPathsWithParamsAgainstRoute( getSourceSegment(rawSegment), getPathIndexShift(rawSegment) + pathIndex + lastChild - 1, newInheritedResolve); + const newInherited = route.component ? + InheritedFromParent.empty(snapshot) : + new InheritedFromParent(inherited, snapshot, parameters, getData(route), newInheritedResolve); + if (slicedPath.length === 0 && segment.hasChildren()) { const children = processSegmentChildren(childConfig, segment, newInherited); return [new TreeNode(snapshot, children)]; @@ -158,13 +160,15 @@ function getChildConfig(route: Route): Route[] { } } -function match(segment: UrlSegment, route: Route, paths: UrlPathWithParams[]) { +function match( + segment: UrlSegment, route: Route, paths: UrlPathWithParams[], parent: ActivatedRouteSnapshot) { if (route.path === '') { if ((route.terminal || route.pathMatch === 'full') && (segment.hasChildren() || paths.length > 0)) { throw new NoMatch(); } else { - return {consumedPaths: [], lastChild: 0, parameters: {}}; + const params = parent ? parent.params : {}; + return {consumedPaths: [], lastChild: 0, parameters: params}; } } diff --git a/modules/@angular/router/test/recognize.spec.ts b/modules/@angular/router/test/recognize.spec.ts index bdf38cb2e7..d3df9332a6 100644 --- a/modules/@angular/router/test/recognize.spec.ts +++ b/modules/@angular/router/test/recognize.spec.ts @@ -262,6 +262,23 @@ describe('recognize', () => { expect(c2._lastPathIndex).toBe(-1); }); }); + + it('should inherit params', () => { + checkRecognize( + [{ + path: 'a', + component: ComponentA, + children: [ + {path: '', component: ComponentB, children: [{path: '', component: ComponentC}]} + ] + }], + '/a;p=1', (s: RouterStateSnapshot) => { + checkActivatedRoute(s.firstChild(s.root), 'a', {p: '1'}, ComponentA); + checkActivatedRoute(s.firstChild(s.firstChild(s.root)), '', {p: '1'}, ComponentB); + checkActivatedRoute( + s.firstChild(s.firstChild(s.firstChild(s.root))), '', {p: '1'}, ComponentC); + }); + }); }); describe('aux split is in the middle', () => {