Skip to content

Commit

Permalink
fix(router): rerun resolvers when url changes
Browse files Browse the repository at this point in the history
  • Loading branch information
vsavkin committed Oct 28, 2016
1 parent 091c390 commit 41a0411
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 9 deletions.
6 changes: 3 additions & 3 deletions modules/@angular/router/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ import {RouterOutlet} from './directives/router_outlet';
import {recognize} from './recognize';
import {LoadedRouterConfig, RouterConfigLoader} from './router_config_loader';
import {RouterOutletMap} from './router_outlet_map';
import {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, advanceActivatedRoute, createEmptyState, inheritedParamsDataResolve} from './router_state';
import {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, advanceActivatedRoute, createEmptyState, equalParamsAndUrlSegments, inheritedParamsDataResolve} from './router_state';
import {NavigationCancelingError, PRIMARY_OUTLET, Params} from './shared';
import {DefaultUrlHandlingStrategy, UrlHandlingStrategy} from './url_handling_strategy';
import {UrlSerializer, UrlTree, containsTree, createEmptyUrlTree} from './url_tree';
import {andObservables, forEach, merge, shallowEqual, waitForMap, wrapIntoObservable} from './utils/collection';
import {andObservables, forEach, merge, waitForMap, wrapIntoObservable} from './utils/collection';
import {TreeNode} from './utils/tree';

declare var Zone: any;
Expand Down Expand Up @@ -830,7 +830,7 @@ export class PreActivation {

// reusing the node
if (curr && future._routeConfig === curr._routeConfig) {
if (!shallowEqual(future.params, curr.params)) {
if (!equalParamsAndUrlSegments(future, curr)) {
this.checks.push(new CanDeactivate(outlet.component, curr), new CanActivate(futurePath));
} else {
// we need to set the data
Expand Down
3 changes: 1 addition & 2 deletions modules/@angular/router/src/router_preloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ export class RouterPreloader {

setUpPreloading(): void {
const navigations = filter.call(this.router.events, (e: any) => e instanceof NavigationEnd);
this.subscription =
concatMap.call(navigations, () => this.preload()).subscribe((v: any) => {});
this.subscription = concatMap.call(navigations, () => this.preload()).subscribe((v: any) => {});
}

preload(): Observable<any> { return this.processRoutes(this.injector, this.router.config); }
Expand Down
8 changes: 7 additions & 1 deletion modules/@angular/router/src/router_state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {Observable} from 'rxjs/Observable';

import {Data, ResolveData, Route} from './config';
import {PRIMARY_OUTLET, Params} from './shared';
import {UrlSegment, UrlSegmentGroup, UrlTree} from './url_tree';
import {UrlSegment, UrlSegmentGroup, UrlTree, equalSegments} from './url_tree';
import {merge, shallowEqual, shallowEqualArrays} from './utils/collection';
import {Tree, TreeNode} from './utils/tree';

Expand Down Expand Up @@ -448,3 +448,9 @@ export function advanceActivatedRoute(route: ActivatedRoute): void {
(<any>route.data).next(route._futureSnapshot.data);
}
}


export function equalParamsAndUrlSegments(
a: ActivatedRouteSnapshot, b: ActivatedRouteSnapshot): boolean {
return shallowEqual(a.params, b.params) && equalSegments(a.url, b.url);
}
26 changes: 25 additions & 1 deletion modules/@angular/router/test/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('Integration', () => {
expect(location.path()).toEqual('/simple');
})));

describe('should execute navigations serialy', () => {
describe('should execute navigations serially', () => {
let log: any[] = [];

beforeEach(() => {
Expand Down Expand Up @@ -693,6 +693,7 @@ describe('Integration', () => {
{provide: 'resolveFour', useValue: (a: any, b: any) => 4},
{provide: 'resolveSix', useClass: ResolveSix},
{provide: 'resolveError', useValue: (a: any, b: any) => Promise.reject('error')},
{provide: 'numberOfUrlSegments', useValue: (a: any, b: any) => a.url.length}
]
});
});
Expand Down Expand Up @@ -787,6 +788,29 @@ describe('Integration', () => {
const cmp = fixture.debugElement.children[1].componentInstance;
expect(cmp.route.snapshot.data).toEqual({two: 2});
})));

it('should rerun resolvers when the urls segments of a wildcard route change',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp);

router.resetConfig([{
path: '**',
component: CollectParamsCmp,
resolve: {numberOfUrlSegments: 'numberOfUrlSegments'}
}]);

let e: any = null;
router.navigateByUrl('/one/two');
advance(fixture);
const cmp = fixture.debugElement.children[1].componentInstance;

expect(cmp.route.snapshot.data).toEqual({numberOfUrlSegments: 2});

router.navigateByUrl('/one/two/three');
advance(fixture);

expect(cmp.route.snapshot.data).toEqual({numberOfUrlSegments: 3});
})));
});

describe('router links', () => {
Expand Down
2 changes: 1 addition & 1 deletion modules/@angular/router/test/router.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,6 @@ function checkResolveData(

function createActivatedRouteSnapshot(cmp: string, extra: any = {}): ActivatedRouteSnapshot {
return new ActivatedRouteSnapshot(
<any>null, {}, <any>null, <any>null, <any>null, <any>null, <any>cmp, <any>null, <any>null, -1,
<any>[], {}, <any>null, <any>null, <any>null, <any>null, <any>cmp, <any>null, <any>null, -1,
extra.resolve);
}
31 changes: 30 additions & 1 deletion modules/@angular/router/test/router_state.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/

import {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot} from '../src/router_state';
import {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, equalParamsAndUrlSegments} from '../src/router_state';
import {Params} from '../src/shared';
import {UrlSegment} from '../src/url_tree';
import {TreeNode} from '../src/utils/tree';

describe('RouterState & Snapshot', () => {
Expand Down Expand Up @@ -93,6 +95,33 @@ describe('RouterState & Snapshot', () => {
expect(p[1]).toBe(b);
});
});

describe('equalParamsAndUrlSegments', () => {
function createSnapshot(params: Params, url: UrlSegment[]): ActivatedRouteSnapshot {
return new ActivatedRouteSnapshot(
url, params, <any>null, <any>null, <any>null, <any>null, <any>null, <any>null, <any>null,
-1, null);
}

it('should return false when params are different', () => {
expect(equalParamsAndUrlSegments(createSnapshot({a: 1}, []), createSnapshot({a: 2}, [])))
.toEqual(false);
});

it('should return false when urls are different', () => {
expect(equalParamsAndUrlSegments(
createSnapshot({a: 1}, [new UrlSegment('a', {})]),
createSnapshot({a: 1}, [new UrlSegment('b', {})])))
.toEqual(false);
});

it('should return true othewise', () => {
expect(equalParamsAndUrlSegments(
createSnapshot({a: 1}, [new UrlSegment('a', {})]),
createSnapshot({a: 1}, [new UrlSegment('a', {})])))
.toEqual(true);
});
});
});

function createActivatedRouteSnapshot(cmp: string) {
Expand Down

0 comments on commit 41a0411

Please sign in to comment.