diff --git a/src/ngRoute/route.js b/src/ngRoute/route.js index 4ecc932b427e..8e772f5cb5b5 100644 --- a/src/ngRoute/route.js +++ b/src/ngRoute/route.js @@ -436,6 +436,21 @@ function $RouteProvider(){ reload: function() { forceReload = true; $rootScope.$evalAsync(updateRoute); + }, + + /** + * @ngdoc method + * @name $route#updateParams + * + * @description + * Causes `$route` service to update the current URL, replacing + * current route parameters with those specified in `newParams`. + * + * @param {Object} newParams mapping of URL parameter names to values + */ + updateParams: function(newParams) { + newParams = angular.extend({}, this.current.params, newParams); + $location.path(interpolate(this.current.$$route.originalPath, newParams)); } }; diff --git a/test/ngRoute/routeSpec.js b/test/ngRoute/routeSpec.js index 072cf6bb8ab7..81f031655dde 100644 --- a/test/ngRoute/routeSpec.js +++ b/test/ngRoute/routeSpec.js @@ -1046,7 +1046,6 @@ describe('$route', function() { }); }); - describe('reload', function() { it('should reload even if reloadOnSearch is false', function() { @@ -1078,4 +1077,75 @@ describe('$route', function() { }); }); }); + + describe('update', function() { + it('should support single-parameter route updating', function() { + var routeChangeSpy = jasmine.createSpy('route change'); + + module(function($routeProvider) { + $routeProvider.when('/bar/:barId', {controller: angular.noop}); + }); + + inject(function($route, $routeParams, $location, $rootScope) { + $rootScope.$on('$routeChangeSuccess', routeChangeSpy); + + $location.path('/bar/1'); + $rootScope.$digest(); + routeChangeSpy.reset(); + + $route.updateParams({barId: '2'}); + $rootScope.$digest(); + + expect($routeParams).toEqual({barId: '2'}); + expect(routeChangeSpy).toHaveBeenCalledOnce(); + expect($location.path()).toEqual('/bar/2'); + }); + }); + + it('should support total multi-parameter route updating', function() { + var routeChangeSpy = jasmine.createSpy('route change'); + + module(function($routeProvider) { + $routeProvider.when('/bar/:barId/:fooId/:spamId/:eggId', {controller: angular.noop}); + }); + + inject(function($route, $routeParams, $location, $rootScope) { + $rootScope.$on('$routeChangeSuccess', routeChangeSpy); + + $location.path('/bar/1/2/3/4'); + $rootScope.$digest(); + routeChangeSpy.reset(); + + $route.updateParams({barId: '5', fooId: '6', spamId: '7', eggId: '8'}); + $rootScope.$digest(); + + expect($routeParams).toEqual({barId: '5', fooId: '6', spamId: '7', eggId: '8'}); + expect(routeChangeSpy).toHaveBeenCalledOnce(); + expect($location.path()).toEqual('/bar/5/6/7/8'); + }); + }); + + it('should support partial multi-parameter route updating', function() { + var routeChangeSpy = jasmine.createSpy('route change'); + + module(function($routeProvider) { + $routeProvider.when('/bar/:barId/:fooId/:spamId/:eggId', {controller: angular.noop}); + }); + + inject(function($route, $routeParams, $location, $rootScope) { + $rootScope.$on('$routeChangeSuccess', routeChangeSpy); + + $location.path('/bar/1/2/3/4'); + $rootScope.$digest(); + routeChangeSpy.reset(); + + $route.updateParams({barId: '5', fooId: '6'}); + $rootScope.$digest(); + + expect($routeParams).toEqual({barId: '5', fooId: '6', spamId: '3', eggId: '4'}); + expect(routeChangeSpy).toHaveBeenCalledOnce(); + expect($location.path()).toEqual('/bar/5/6/3/4'); + }); + }); + }); });