From f8a7c7ec2245350284c6fe8d00e4bd73c1214e4d Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Mon, 18 Apr 2011 09:13:59 -0700 Subject: [PATCH] add $route#watchHashPathOnly if $route.watchHashPathOnly(true) is called, all subsequent route reloads will be triggered only if hashPath and not hashSearch changes --- src/service/route.js | 19 +++++++++++++++++-- test/service/routeSpec.js | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/service/route.js b/src/service/route.js index 19fc81bff076..c932de8e4c76 100644 --- a/src/service/route.js +++ b/src/service/route.js @@ -8,7 +8,7 @@ * @property {Array.} routes Array of all configured routes. * * @description - * Watches `$location.hashPath` and tries to map the hash to an existing route + * Watches `$location.hash` and tries to map the hash to an existing route * definition. It is used for deep-linking URLs to controllers and views (HTML partials). * * The `$route` service is typically used in conjunction with {@link angular.widget.ng:view ng:view} @@ -62,6 +62,7 @@ angularServiceInject('$route', function(location, $updateView) { matcher = switchRouteMatcher, parentScope = this, dirty = 0, + locationWatchProp = 'hash', $route = { routes: routes, @@ -172,6 +173,20 @@ angularServiceInject('$route', function(location, $updateView) { */ reload: function() { dirty++; + }, + + /** + * @workInProgress + * @ngdoc method + * @name angular.service.$route#watchHashPathOnly + * @methodOf angular.service.$route + * + * @description + * Causes `$route` service to be reload only if `$location.hashPath` changes. Other properties of + * {@link angular.service.$location $location service} won't trigger reloads. + */ + watchHashPathOnly: function(hashPathOnly) { + locationWatchProp = hashPathOnly ? 'hashPath' : 'hash'; } }; @@ -260,7 +275,7 @@ angularServiceInject('$route', function(location, $updateView) { } - this.$watch(function(){return dirty + location.hash;}, updateRoute); + this.$watch(function(){return dirty + location[locationWatchProp];}, updateRoute); return $route; }, ['$location', '$updateView']); diff --git a/test/service/routeSpec.js b/test/service/routeSpec.js index ccdf19eca881..bedf18951790 100644 --- a/test/service/routeSpec.js +++ b/test/service/routeSpec.js @@ -11,7 +11,7 @@ describe('$route', function() { }); - it('should route and fire change event', function(){ + it('should change route and fire change event', function(){ var log = '', $location, $route; @@ -52,6 +52,42 @@ describe('$route', function() { }); + it('should not reload route when only hashSearch changes, but hashPath does not', function() { + var scope = angular.scope(), + $location = scope.$service('$location'), + $route = scope.$service('$route'), + log = []; + + $route.when('/foo', {controller: FooCtrl}); + + function FooCtrl() { + log.push('foo'); + } + + expect(log).toEqual([]); + + //without watchHashPathOnly setting the route should always reload + $location.hashPath = '/foo'; + scope.$eval(); + $location.hashSearch.foo = 'bar'; + scope.$eval(); + expect(log).toEqual(['foo', 'foo']); + + //reset log and change $route config + log = []; + $route.watchHashPathOnly(true); + + //with watchHashPathOnly on, only hashPath changes should not trigger reload + $location.hashPath = '/foo'; + scope.$eval(); + expect(log).toEqual(['foo']); + + $location.hashSearch.foo = 'bar'; + scope.$eval(); + expect(log).toEqual(['foo']); + }); + + it('should return fn registered with onChange()', function() { var scope = angular.scope(), $route = scope.$service('$route'),