Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit a4fe51d

Browse files
committed
feat($route): when matching consider trailing slash as optional
This makes for a much more flexible route matching: - route /foo matches /foo and redirects /foo/ to /foo - route /bar/ matches /bar/ and redirects /bar to /bar/ Closes #784
1 parent ee5a535 commit a4fe51d

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

src/service/route.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ function $RouteProvider(){
1818
* @name angular.module.ng.$routeProvider#when
1919
* @methodOf angular.module.ng.$routeProvider
2020
*
21-
* @param {string} path Route path (matched against `$location.hash`)
21+
* @param {string} path Route path (matched against `$location.path`). If `$location.path`
22+
* contains redudant trailing slash or is missing one, the route will still match and the
23+
* `$location.path` will be updated to add or drop the trailing slash to exacly match the
24+
* route definition.
2225
* @param {Object} route Mapping information to be assigned to `$route.current` on route
2326
* match.
2427
*
@@ -57,6 +60,16 @@ function $RouteProvider(){
5760
var routeDef = routes[path];
5861
if (!routeDef) routeDef = routes[path] = {reloadOnSearch: true};
5962
if (route) extend(routeDef, route); // TODO(im): what the heck? merge two route definitions?
63+
64+
// create redirection for trailing slashes
65+
if (path) {
66+
var redirectPath = (path[path.length-1] == '/')
67+
? path.substr(0, path.length-1)
68+
: path +'/';
69+
70+
routes[redirectPath] = {redirectTo: path};
71+
}
72+
6073
return routeDef;
6174
};
6275

test/service/routeSpec.js

+30
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,36 @@ describe('$route', function() {
168168
});
169169

170170

171+
it('should match route with and without trailing slash', function() {
172+
module(function($routeProvider){
173+
$routeProvider.when('/foo', {template: 'foo.html'});
174+
$routeProvider.when('/bar/', {template: 'bar.html'});
175+
});
176+
177+
inject(function($route, $location, $rootScope) {
178+
$location.path('/foo');
179+
$rootScope.$digest();
180+
expect($location.path()).toBe('/foo');
181+
expect($route.current.template).toBe('foo.html');
182+
183+
$location.path('/foo/');
184+
$rootScope.$digest();
185+
expect($location.path()).toBe('/foo');
186+
expect($route.current.template).toBe('foo.html');
187+
188+
$location.path('/bar');
189+
$rootScope.$digest();
190+
expect($location.path()).toBe('/bar/');
191+
expect($route.current.template).toBe('bar.html');
192+
193+
$location.path('/bar/');
194+
$rootScope.$digest();
195+
expect($location.path()).toBe('/bar/');
196+
expect($route.current.template).toBe('bar.html');
197+
});
198+
});
199+
200+
171201
describe('redirection', function() {
172202
it('should support redirection via redirectTo property by updating $location', function() {
173203
module(function($routeProvider) {

0 commit comments

Comments
 (0)