diff --git a/modules/@angular/router/src/router.ts b/modules/@angular/router/src/router.ts index 3b203e85af..a4984b5653 100644 --- a/modules/@angular/router/src/router.ts +++ b/modules/@angular/router/src/router.ts @@ -151,7 +151,7 @@ export class Router { (change) => { this._navigate(this._urlSerializer.parse(change['url']), change['pop']); }); } - private _navigate(url: UrlTree, pop?: boolean): Promise { + private _navigate(url: UrlTree, preventPushState?: boolean): Promise { this._urlTree = url; return recognize(this._componentResolver, this._rootComponentType, url, this._routeTree) .then(currTree => { @@ -160,8 +160,13 @@ export class Router { .then(updated => { if (updated) { this._routeTree = currTree; - if (isBlank(pop) || !pop) { - this._location.go(this._urlSerializer.serialize(this._urlTree)); + if (isBlank(preventPushState) || !preventPushState) { + let path = this._urlSerializer.serialize(this._urlTree); + if (this._location.isCurrentPathEqualTo(path)) { + this._location.replaceState(path); + } else { + this._location.go(path); + } } this._changes.emit(null); } diff --git a/modules/@angular/router/test/integration_spec.ts b/modules/@angular/router/test/integration_spec.ts index 5ae75f15a7..2a9477fa99 100644 --- a/modules/@angular/router/test/integration_spec.ts +++ b/modules/@angular/router/test/integration_spec.ts @@ -252,6 +252,24 @@ export function main() { advance(fixture); expect(fixture.debugElement.nativeElement).toHaveText('link'); }))); + + it('should replace state when path is equal to current path', + fakeAsync(inject([Router, TestComponentBuilder, Location], (router, tcb, location) => { + let fixture = tcb.createFakeAsync(RootCmp); + + router.navigateByUrl('/team/33/simple'); + advance(fixture); + + router.navigateByUrl('/team/22/user/victor'); + advance(fixture); + + router.navigateByUrl('/team/22/user/victor'); + advance(fixture); + + location.back(); + advance(fixture); + expect(location.path()).toEqual('/team/33/simple'); + }))); } }); }