diff --git a/src/ng/route.js b/src/ng/route.js index 12e560c76535..820e31770295 100644 --- a/src/ng/route.js +++ b/src/ng/route.js @@ -277,6 +277,11 @@ function $RouteProvider(){ * defined in `resolve` route property. Once all of the dependencies are resolved * `$routeChangeSuccess` is fired. * + * Call event.preventDefault() to prevent changing route but leave the browser Url + * to it's new location (as opposed to calling event.preventDefault() on $location's + * $locationChangeStart event which cancels changing the browser's Url). + * + * * @param {Route} next Future route information. * @param {Route} current Current route information. */ @@ -407,7 +412,9 @@ function $RouteProvider(){ $rootScope.$broadcast('$routeUpdate', last); } else if (next || last) { forceReload = false; - $rootScope.$broadcast('$routeChangeStart', next, last); + if ( $rootScope.$broadcast('$routeChangeStart', next, last).defaultPrevented ){ + return; + } $route.current = next; if (next) { if (next.redirectTo) { diff --git a/test/ng/routeSpec.js b/test/ng/routeSpec.js index c26512862c92..a54250a37e07 100644 --- a/test/ng/routeSpec.js +++ b/test/ng/routeSpec.js @@ -205,6 +205,28 @@ describe('$route', function() { }); + it('should not change route when $routeChangeStart is canceled', function() { + module(function($routeProvider) { + $routeProvider.when('/somePath', {template: 'some path'}); + }); + inject(function($route, $location, $rootScope, $log) { + $rootScope.$on('$routeChangeStart', function(event) { + $log.info('$routeChangeStart'); + event.preventDefault(); + }); + + $rootScope.$on('$routeChangeSuccess', function(event) { + throw new Error('Should not get here'); + }); + + $location.path('/somePath'); + $rootScope.$digest(); + + expect($log.info.logs.shift()).toEqual(['$routeChangeStart']); + }); + }); + + describe('should match a route that contains special chars in the path', function() { beforeEach(module(function($routeProvider) { $routeProvider.when('/$test.23/foo*(bar)/:baz', {templateUrl: 'test.html'});