diff --git a/modules/@angular/router/src/router_state.ts b/modules/@angular/router/src/router_state.ts index 6f746fe6dd..8df82dcb93 100644 --- a/modules/@angular/router/src/router_state.ts +++ b/modules/@angular/router/src/router_state.ts @@ -13,7 +13,7 @@ import {Observable} from 'rxjs/Observable'; import {Route} from './config'; import {PRIMARY_OUTLET, Params} from './shared'; import {UrlPathWithParams, UrlSegment, UrlTree} from './url_tree'; -import {shallowEqual} from './utils/collection'; +import {shallowEqual, shallowEqualArrays} from './utils/collection'; import {Tree, TreeNode} from './utils/tree'; @@ -188,10 +188,14 @@ function serializeNode(node: TreeNode): string { * And we detect that by checking if the snapshot field is set. */ export function advanceActivatedRoute(route: ActivatedRoute): void { - if (route.snapshot && !shallowEqual(route.snapshot.params, route._futureSnapshot.params)) { + if (route.snapshot) { + if (!shallowEqual(route.snapshot.params, route._futureSnapshot.params)) { + (route.params).next(route._futureSnapshot.params); + } + if (!shallowEqualArrays(route.snapshot.url, route._futureSnapshot.url)) { + (route.url).next(route._futureSnapshot.url); + } route.snapshot = route._futureSnapshot; - (route.url).next(route.snapshot.url); - (route.params).next(route.snapshot.params); } else { route.snapshot = route._futureSnapshot; } diff --git a/modules/@angular/router/src/utils/collection.ts b/modules/@angular/router/src/utils/collection.ts index e022a95f5c..a9139715c2 100644 --- a/modules/@angular/router/src/utils/collection.ts +++ b/modules/@angular/router/src/utils/collection.ts @@ -6,6 +6,14 @@ * found in the LICENSE file at https://angular.io/license */ +export function shallowEqualArrays(a:any[], b:any[]):boolean { + if (a.length !== b.length) return false; + for (let i = 0; i < a.length; ++i) { + if (!shallowEqual(a[i], b[i])) return false; + } + return true; +} + export function shallowEqual(a: {[x: string]: any}, b: {[x: string]: any}): boolean { const k1 = Object.keys(a); const k2 = Object.keys(b); diff --git a/modules/@angular/router/test/router.spec.ts b/modules/@angular/router/test/router.spec.ts index 7140ce7f1d..9ea6c9b915 100644 --- a/modules/@angular/router/test/router.spec.ts +++ b/modules/@angular/router/test/router.spec.ts @@ -133,17 +133,21 @@ describe('Integration', () => { const fixture = tcb.createFakeAsync(RootCmp); advance(fixture); - router.resetConfig([{path: '**', component: SimpleCmp}]); + router.resetConfig([{path: '**', component: CollectParamsCmp}]); router.navigateByUrl('/one/two'); advance(fixture); + const cmp = fixture.debugElement.children[1].componentInstance; expect(location.path()).toEqual('/one/two'); - expect(fixture.debugElement.nativeElement).toHaveText('simple'); + expect(fixture.debugElement.nativeElement).toHaveText('collect-params'); + + expect(cmp.recordedUrls()).toEqual(['one/two']); router.navigateByUrl('/three/four'); advance(fixture); expect(location.path()).toEqual('/three/four'); - expect(fixture.debugElement.nativeElement).toHaveText('simple'); + expect(fixture.debugElement.nativeElement).toHaveText('collect-params'); + expect(cmp.recordedUrls()).toEqual(['one/two', 'three/four']); }))); it('should support secondary routes', @@ -1025,6 +1029,21 @@ class LinkWithQueryParamsAndFragment { class SimpleCmp { } +@Component({selector: 'collect-params-cmp', template: `collect-params`, directives: ROUTER_DIRECTIVES}) +class CollectParamsCmp { + private params: any = []; + private urls: any = []; + + constructor(a: ActivatedRoute) { + a.params.forEach(p => this.params.push(p)); + a.url.forEach(u => this.urls.push(u)); + } + + recordedUrls(): string[] { + return this.urls.map(a => a.map(p => p.path).join('/')); + } +} + @Component({selector: 'blank-cmp', template: ``, directives: ROUTER_DIRECTIVES}) class BlankCmp { }