diff --git a/modules/@angular/router/src/router_state.ts b/modules/@angular/router/src/router_state.ts index 34f82d2d5c2bf..7fa52a43894ed 100644 --- a/modules/@angular/router/src/router_state.ts +++ b/modules/@angular/router/src/router_state.ts @@ -356,5 +356,9 @@ export function advanceActivatedRoute(route: ActivatedRoute): void { export function equalParamsAndUrlSegments( a: ActivatedRouteSnapshot, b: ActivatedRouteSnapshot): boolean { - return shallowEqual(a.params, b.params) && equalSegments(a.url, b.url); -} + const equalUrlParams = shallowEqual(a.params, b.params) && equalSegments(a.url, b.url); + const parentsMismatch = !a.parent !== !b.parent; + + return equalUrlParams && !parentsMismatch && + (!a.parent || equalParamsAndUrlSegments(a.parent, b.parent)); +} \ No newline at end of file diff --git a/modules/@angular/router/test/router_state.spec.ts b/modules/@angular/router/test/router_state.spec.ts index 1076629b02716..6417c7d9d72b7 100644 --- a/modules/@angular/router/test/router_state.spec.ts +++ b/modules/@angular/router/test/router_state.spec.ts @@ -100,9 +100,28 @@ describe('RouterState & Snapshot', () => { describe('equalParamsAndUrlSegments', () => { function createSnapshot(params: Params, url: UrlSegment[]): ActivatedRouteSnapshot { - return new ActivatedRouteSnapshot( + const snapshot = new ActivatedRouteSnapshot( url, params, null, null, null, null, null, null, null, -1, null); + snapshot._routerState = new RouterStateSnapshot('', new TreeNode(snapshot, [])); + return snapshot; + } + + function createSnapshotPairWithParent( + params: [Params, Params], parentParams: [Params, Params], + urls: [string, string]): [ActivatedRouteSnapshot, ActivatedRouteSnapshot] { + const snapshot1 = createSnapshot(params[0], []); + const snapshot2 = createSnapshot(params[1], []); + + const snapshot1Parent = createSnapshot(parentParams[0], [new UrlSegment(urls[0], {})]); + const snapshot2Parent = createSnapshot(parentParams[1], [new UrlSegment(urls[1], {})]); + + snapshot1._routerState = + new RouterStateSnapshot('', new TreeNode(snapshot1Parent, [new TreeNode(snapshot1, [])])); + snapshot2._routerState = + new RouterStateSnapshot('', new TreeNode(snapshot2Parent, [new TreeNode(snapshot2, [])])); + + return [snapshot1, snapshot2]; } it('should return false when params are different', () => { @@ -123,6 +142,27 @@ describe('RouterState & Snapshot', () => { createSnapshot({a: 1}, [new UrlSegment('a', {})]))) .toEqual(true); }); + + it('should return false when upstream params are different', () => { + const [snapshot1, snapshot2] = + createSnapshotPairWithParent([{a: 1}, {a: 1}], [{b: 1}, {c: 1}], ['a', 'a']); + + expect(equalParamsAndUrlSegments(snapshot1, snapshot2)).toEqual(false); + }); + + it('should return false when upstream urls are different', () => { + const [snapshot1, snapshot2] = + createSnapshotPairWithParent([{a: 1}, {a: 1}], [{b: 1}, {b: 1}], ['a', 'b']); + + expect(equalParamsAndUrlSegments(snapshot1, snapshot2)).toEqual(false); + }); + + it('should return true when upstream urls and params are equal', () => { + const [snapshot1, snapshot2] = + createSnapshotPairWithParent([{a: 1}, {a: 1}], [{b: 1}, {b: 1}], ['a', 'a']); + + expect(equalParamsAndUrlSegments(snapshot1, snapshot2)).toEqual(true); + }); }); describe('advanceActivatedRoute', () => { @@ -135,9 +175,12 @@ describe('RouterState & Snapshot', () => { const queryParams = {}; const fragment = ''; const data = {}; - return new ActivatedRouteSnapshot( + const snapshot = new ActivatedRouteSnapshot( url, params, queryParams, fragment, data, null, null, null, null, -1, null); + const state = new RouterStateSnapshot('', new TreeNode(snapshot, [])); + snapshot._routerState = state; + return snapshot; } it('should call change observers', () => {