diff options
| -rw-r--r-- | src/services.js | 49 | ||||
| -rw-r--r-- | test/servicesSpec.js | 43 |
2 files changed, 75 insertions, 17 deletions
diff --git a/src/services.js b/src/services.js index 395c1298..d6a7fb0a 100644 --- a/src/services.js +++ b/src/services.js @@ -690,6 +690,18 @@ angularServiceInject('$route', function(location) { * @param {string} path Route path (matched against `$location.hash`) * @param {Object} params Mapping information to be assigned to `$route.current` on route * match. + * + * Object properties: + * + * - `controller` – `{function()=}` – Controller fn that should be associated with newly + * created scope. + * - `template` – `{string=}` – path to an html template that should be used by + * {@link angular.widget.ng:view ng:view} or + * {@link angular.widget.ng:include ng:include} widgets. + * - `redirectTo` – {string=} – value to update + * {@link angular.service.$location $location} hash with and trigger route + * redirection. + * * @returns {Object} route object * * @description @@ -721,28 +733,31 @@ angularServiceInject('$route', function(location) { } }; function updateRoute(){ - var childScope; + var childScope, routeParams, pathParams; + $route.current = _null; - forEach(routes, function(routeParams, route) { - if (!childScope) { - var pathParams = matcher(location.hashPath, route); - if (pathParams) { - childScope = createScope(parentScope); - $route.current = extend({}, routeParams, { - scope: childScope, - params: extend({}, location.hashSearch, pathParams) - }); + forEach(routes, function(rParams, rPath) { + if (!pathParams) { + if (pathParams = matcher(location.hashPath, rPath)) { + routeParams = rParams; } } }); - //fallback - if (!childScope && routes[_null]) { - childScope = createScope(parentScope); - $route.current = extend({}, routes[_null], { - scope: childScope, - params: extend({}, location.hashSearch) - }); + // "otherwise" fallback + routeParams = routeParams || routes[_null]; + + if(routeParams) { + if (routeParams.redirectTo) { + location.updateHash(routeParams.redirectTo); //let $browser trigger next route change + return; + } else { + childScope = createScope(parentScope); + $route.current = extend({}, routeParams, { + scope: childScope, + params: extend({}, location.hashSearch, pathParams) + }); + } } //fire onChange callbacks diff --git a/test/servicesSpec.js b/test/servicesSpec.js index f7151dbc..ddad5d89 100644 --- a/test/servicesSpec.js +++ b/test/servicesSpec.js @@ -460,6 +460,49 @@ describe("service", function(){ expect($route.current.scope.notFoundProp).toBeUndefined(); expect(onChangeSpy).toHaveBeenCalled(); }); + + it('should support redirection via redirectTo property by updating $location', function() { + var scope = angular.scope(), + $location = scope.$service('$location'), + $browser = scope.$service('$browser'), + $route = scope.$service('$route'), + onChangeSpy = jasmine.createSpy('onChange'); + + $route.when('', {redirectTo: '/foo'}); + $route.when('/foo', {template: 'foo.html'}); + $route.when('/bar', {template: 'bar.html'}); + $route.when('/baz', {redirectTo: '/bar'}); + $route.otherwise({template: '404.html'}); + $route.onChange(onChangeSpy); + expect($route.current).toBeNull(); + expect(onChangeSpy).not.toHaveBeenCalled(); + + scope.$eval(); //triggers initial route change - match the redirect route + $browser.poll(); //triger route change - match the route we redirected to + + expect($location.hash).toBe('/foo'); + expect($route.current.template).toBe('foo.html'); + expect(onChangeSpy.callCount).toBe(1); + + onChangeSpy.reset(); + $location.updateHash(''); + scope.$eval(); //match the redirect route + update $browser + $browser.poll(); //match the route we redirected to + + + expect($location.hash).toBe('/foo'); + expect($route.current.template).toBe('foo.html'); + expect(onChangeSpy.callCount).toBe(1); + + onChangeSpy.reset(); + $location.updateHash('/baz'); + scope.$eval(); //match the redirect route + update $browser + $browser.poll(); //match the route we redirected to + + expect($location.hash).toBe('/bar'); + expect($route.current.template).toBe('bar.html'); + expect(onChangeSpy.callCount).toBe(1); + }); }); |
