aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/services.js49
-rw-r--r--test/servicesSpec.js43
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);
+ });
});