fix(router): reset URL to the stable state when a navigation gets canceled

Closes #10321
This commit is contained in:
vsavkin 2016-11-02 11:30:00 -07:00
parent 8e221b826f
commit d509ee078b
3 changed files with 42 additions and 8 deletions

View File

@ -702,7 +702,7 @@ export class Router {
this.currentRouterState = state;
if (!shouldPreventPushState) {
let path = this.urlSerializer.serialize(this.rawUrlTree);
const path = this.urlSerializer.serialize(this.rawUrlTree);
if (this.location.isCurrentPathEqualTo(path) || shouldReplaceUrl) {
this.location.replaceState(path);
} else {
@ -722,12 +722,14 @@ export class Router {
new NavigationEnd(id, this.serializeUrl(url), this.serializeUrl(appliedUrl)));
resolvePromise(true);
} else {
this.resetUrlToCurrentUrlTree();
this.routerEvents.next(new NavigationCancel(id, this.serializeUrl(url), ''));
resolvePromise(false);
}
},
(e: any) => {
if (e instanceof NavigationCancelingError) {
this.resetUrlToCurrentUrlTree();
this.navigated = true;
this.routerEvents.next(
new NavigationCancel(id, this.serializeUrl(url), e.message));
@ -741,15 +743,18 @@ export class Router {
}
}
if (id === this.navigationId) {
this.currentRouterState = storedState;
this.currentUrlTree = storedUrl;
this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
this.location.replaceState(this.serializeUrl(this.rawUrlTree));
}
this.currentRouterState = storedState;
this.currentUrlTree = storedUrl;
this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
this.location.replaceState(this.serializeUrl(this.rawUrlTree));
});
});
}
private resetUrlToCurrentUrlTree(): void {
const path = this.urlSerializer.serialize(this.rawUrlTree);
this.location.replaceState(path);
}
}

View File

@ -1213,6 +1213,35 @@ describe('Integration', () => {
expect(location.path()).toEqual('/team/22');
})));
});
describe('should reset the location when cancleling a navigation', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [{
provide: 'alwaysFalse',
useValue: (a: ActivatedRouteSnapshot, b: RouterStateSnapshot) => { return false; }
}]
});
});
it('works', fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp);
router.resetConfig([
{path: 'one', component: SimpleCmp},
{path: 'two', component: SimpleCmp, canActivate: ['alwaysFalse']}
]);
router.navigateByUrl('/one');
advance(fixture);
expect(location.path()).toEqual('/one');
location.go('/two');
advance(fixture);
expect(location.path()).toEqual('/one');
})));
});
});
describe('CanDeactivate', () => {

View File

@ -228,7 +228,7 @@ export declare class RouterLink {
routerLink: any[] | string;
urlTree: UrlTree;
constructor(router: Router, route: ActivatedRoute, locationStrategy: LocationStrategy);
onClick(button: number, ctrlKey: boolean, metaKey: boolean): boolean;
onClick(): boolean;
}
/** @stable */