From cb6574497af8990d1569c0df78132d4d2911c55b Mon Sep 17 00:00:00 2001 From: Georgios Kalpakas Date: Sat, 30 Jan 2016 01:35:14 +0200 Subject: [PATCH] feat($route): add support for preventing a route reload Fixes #9824 --- src/ngRoute/route.js | 14 ++++- test/ngRoute/routeSpec.js | 117 +++++++++++++++++++++++++++++++------- 2 files changed, 106 insertions(+), 25 deletions(-) diff --git a/src/ngRoute/route.js b/src/ngRoute/route.js index e47b53e3eca1..90db1140d0bc 100644 --- a/src/ngRoute/route.js +++ b/src/ngRoute/route.js @@ -479,10 +479,18 @@ function $RouteProvider() { */ reload: function() { forceReload = true; + + var fakeLocationEvent = { + defaultPrevented: false, + preventDefault: function fakePreventDefault() { + this.defaultPrevented = true; + forceReload = false; + } + }; + $rootScope.$evalAsync(function() { - // Don't support cancellation of a reload for now... - prepareRoute(); - commitRoute(); + prepareRoute(fakeLocationEvent); + if (!fakeLocationEvent.defaultPrevented) commitRoute(); }); }, diff --git a/test/ngRoute/routeSpec.js b/test/ngRoute/routeSpec.js index 368dadf3c9ae..1305ba51cfe0 100644 --- a/test/ngRoute/routeSpec.js +++ b/test/ngRoute/routeSpec.js @@ -303,7 +303,7 @@ describe('$route', function() { event.preventDefault(); }); - $rootScope.$on('$beforeRouteChange', function(event) { + $rootScope.$on('$routeChangeSuccess', function(event) { throw new Error('Should not get here'); }); @@ -1214,34 +1214,107 @@ describe('$route', function() { }); describe('reload', function() { + var $location; + var $log; + var $rootScope; + var $route; + var routeChangeStartSpy; + var routeChangeSuccessSpy; + + beforeEach(module(function($routeProvider) { + $routeProvider.when('/bar/:barId', { + template: '', + controller: controller, + reloadOnSearch: false + }); - it('should reload even if reloadOnSearch is false', function() { - var routeChangeSpy = jasmine.createSpy('route change'); + function controller($log) { + $log.debug('initialized'); + } + })); + beforeEach(inject(function($compile, _$location_, _$log_, _$rootScope_, _$route_) { + $location = _$location_; + $log = _$log_; + $rootScope = _$rootScope_; + $route = _$route_; - module(function($routeProvider) { - $routeProvider.when('/bar/:barId', {controller: angular.noop, reloadOnSearch: false}); - }); + routeChangeStartSpy = jasmine.createSpy('routeChangeStart'); + routeChangeSuccessSpy = jasmine.createSpy('routeChangeSuccess'); - inject(function($route, $location, $rootScope, $routeParams) { - $rootScope.$on('$routeChangeSuccess', routeChangeSpy); + $rootScope.$on('$routeChangeStart', routeChangeStartSpy); + $rootScope.$on('$routeChangeSuccess', routeChangeSuccessSpy); - $location.path('/bar/123'); - $rootScope.$digest(); - expect($routeParams).toEqual({barId:'123'}); - expect(routeChangeSpy).toHaveBeenCalledOnce(); - routeChangeSpy.reset(); + element = $compile('
')($rootScope); + })); - $location.path('/bar/123').search('a=b'); - $rootScope.$digest(); - expect($routeParams).toEqual({barId:'123', a:'b'}); - expect(routeChangeSpy).not.toHaveBeenCalled(); + it('should reload the current route', function() { + $location.path('/bar/123'); + $rootScope.$digest(); + expect($location.path()).toBe('/bar/123'); + expect(routeChangeStartSpy).toHaveBeenCalledOnce(); + expect(routeChangeSuccessSpy).toHaveBeenCalledOnce(); + expect($log.debug.logs).toEqual([['initialized']]); - $route.reload(); - $rootScope.$digest(); - expect($routeParams).toEqual({barId:'123', a:'b'}); - expect(routeChangeSpy).toHaveBeenCalledOnce(); - }); + routeChangeStartSpy.reset(); + routeChangeSuccessSpy.reset(); + $log.reset(); + + $route.reload(); + $rootScope.$digest(); + expect($location.path()).toBe('/bar/123'); + expect(routeChangeStartSpy).toHaveBeenCalledOnce(); + expect(routeChangeSuccessSpy).toHaveBeenCalledOnce(); + expect($log.debug.logs).toEqual([['initialized']]); + + $log.reset(); + }); + + it('should support preventing a route reload', function() { + $location.path('/bar/123'); + $rootScope.$digest(); + expect($location.path()).toBe('/bar/123'); + expect(routeChangeStartSpy).toHaveBeenCalledOnce(); + expect(routeChangeSuccessSpy).toHaveBeenCalledOnce(); + expect($log.debug.logs).toEqual([['initialized']]); + + routeChangeStartSpy.reset(); + routeChangeSuccessSpy.reset(); + $log.reset(); + + routeChangeStartSpy.andCallFake(function(evt) { evt.preventDefault(); }); + + $route.reload(); + $rootScope.$digest(); + expect($location.path()).toBe('/bar/123'); + expect(routeChangeStartSpy).toHaveBeenCalledOnce(); + expect(routeChangeSuccessSpy).not.toHaveBeenCalled(); + expect($log.debug.logs).toEqual([]); }); + + it('should reload even if reloadOnSearch is false', inject(function($routeParams) { + $location.path('/bar/123'); + $rootScope.$digest(); + expect($routeParams).toEqual({barId: '123'}); + expect(routeChangeSuccessSpy).toHaveBeenCalledOnce(); + expect($log.debug.logs).toEqual([['initialized']]); + + routeChangeSuccessSpy.reset(); + $log.reset(); + + $location.search('a=b'); + $rootScope.$digest(); + expect($routeParams).toEqual({barId: '123', a: 'b'}); + expect(routeChangeSuccessSpy).not.toHaveBeenCalled(); + expect($log.debug.logs).toEqual([]); + + $route.reload(); + $rootScope.$digest(); + expect($routeParams).toEqual({barId: '123', a: 'b'}); + expect(routeChangeSuccessSpy).toHaveBeenCalledOnce(); + expect($log.debug.logs).toEqual([['initialized']]); + + $log.reset(); + })); }); });