mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +00:00
add support for hashSearch redirection and custom redirection functions
This commit is contained in:
parent
8724e97b7e
commit
86321d1f57
2 changed files with 75 additions and 27 deletions
|
|
@ -748,13 +748,23 @@ angularServiceInject('$route', function(location, $updateView) {
|
|||
* Object properties:
|
||||
*
|
||||
* - `controller` – `{function()=}` – Controller fn that should be associated with newly
|
||||
* created scope.
|
||||
* 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.
|
||||
* {@link angular.widget.ng:view ng:view} or
|
||||
* {@link angular.widget.ng:include ng:include} widgets.
|
||||
* - `redirectTo` – {(string|function())=} – value to update
|
||||
* {@link angular.service.$location $location} hash with and trigger route redirection.
|
||||
*
|
||||
* If `redirectTo` is a function, it will be called with the following parameters:
|
||||
*
|
||||
* - `{Object.<string>}` - route parameters extracted from the current
|
||||
* `$location.hashPath` by applying the current route template.
|
||||
* - `{string}` - current `$location.hash`
|
||||
* - `{string}` - current `$location.hashPath`
|
||||
* - `{string}` - current `$location.hashSearch`
|
||||
*
|
||||
* The custom `redirectTo` function is expected to return a string which will be used
|
||||
* to update `$location.hash`.
|
||||
*
|
||||
* @returns {Object} route object
|
||||
*
|
||||
|
|
@ -801,7 +811,7 @@ angularServiceInject('$route', function(location, $updateView) {
|
|||
}
|
||||
};
|
||||
function updateRoute(){
|
||||
var childScope, routeParams, pathParams, redirectPath, segmentMatch, key;
|
||||
var childScope, routeParams, pathParams, segmentMatch, key, redir;
|
||||
|
||||
$route.current = _null;
|
||||
forEach(routes, function(rParams, rPath) {
|
||||
|
|
@ -817,18 +827,29 @@ angularServiceInject('$route', function(location, $updateView) {
|
|||
|
||||
if(routeParams) {
|
||||
if (routeParams.redirectTo) {
|
||||
redirectPath = '';
|
||||
forEach(routeParams.redirectTo.split(':'), function(segment, i) {
|
||||
if (i==0) {
|
||||
redirectPath += segment;
|
||||
} else {
|
||||
segmentMatch = segment.match(/(\w+)(.*)/);
|
||||
key = segmentMatch[1];
|
||||
redirectPath += pathParams[key] || location.hashSearch[key];
|
||||
redirectPath += segmentMatch[2] || '';
|
||||
}
|
||||
});
|
||||
location.updateHash(redirectPath);
|
||||
if (isString(routeParams.redirectTo)) {
|
||||
// interpolate the redirectTo string
|
||||
redir = {hashPath: '',
|
||||
hashSearch: extend({}, location.hashSearch, pathParams)};
|
||||
|
||||
forEach(routeParams.redirectTo.split(':'), function(segment, i) {
|
||||
if (i==0) {
|
||||
redir.hashPath += segment;
|
||||
} else {
|
||||
segmentMatch = segment.match(/(\w+)(.*)/);
|
||||
key = segmentMatch[1];
|
||||
redir.hashPath += pathParams[key] || location.hashSearch[key];
|
||||
redir.hashPath += segmentMatch[2] || '';
|
||||
delete redir.hashSearch[key];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// call custom redirectTo function
|
||||
redir = {hash: routeParams.redirectTo(pathParams, location.hash, location.hashPath,
|
||||
location.hashSearch)};
|
||||
}
|
||||
|
||||
location.update(redir);
|
||||
$updateView(); //TODO this is to work around the $location<=>$browser issues
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -523,14 +523,14 @@ describe("service", function(){
|
|||
expect(onChangeSpy.callCount).toBe(1);
|
||||
});
|
||||
|
||||
|
||||
it('should interpolate route variables in the redirected path from hashPath', function() {
|
||||
it('should interpolate route variables in the redirected hashPath from the original hashPath',
|
||||
function() {
|
||||
var scope = angular.scope(),
|
||||
$location = scope.$service('$location'),
|
||||
$browser = scope.$service('$browser'),
|
||||
$route = scope.$service('$route');
|
||||
|
||||
$route.when('/foo/:id/foo/:subid/:ignoredId', {redirectTo: '/bar/:id/:subid/23'});
|
||||
$route.when('/foo/:id/foo/:subid/:extraId', {redirectTo: '/bar/:id/:subid/23'});
|
||||
$route.when('/bar/:id/:subid/:subsubid', {template: 'bar.html'});
|
||||
scope.$eval();
|
||||
|
||||
|
|
@ -538,27 +538,54 @@ describe("service", function(){
|
|||
scope.$eval(); //triggers initial route change - match the redirect route
|
||||
$browser.defer.flush(); //triger route change - match the route we redirected to
|
||||
|
||||
expect($location.hash).toBe('/bar/id1/subid3/23');
|
||||
expect($location.hash).toBe('/bar/id1/subid3/23?extraId=gah');
|
||||
expect($route.current.template).toBe('bar.html');
|
||||
});
|
||||
|
||||
it('should interpolate route variables in the redirected path from hashSearch', function() {
|
||||
it('should interpolate route variables in the redirected hashPath from the original hashSearch',
|
||||
function() {
|
||||
var scope = angular.scope(),
|
||||
$location = scope.$service('$location'),
|
||||
$browser = scope.$service('$browser'),
|
||||
$route = scope.$service('$route');
|
||||
|
||||
$route.when('/bar/:id/:subid/:subsubid', {template: 'bar.html'});
|
||||
$route.when('/foo/:id', {redirectTo: '/bar/:id/:subid/99'});
|
||||
$route.when('/foo/:id/:extra', {redirectTo: '/bar/:id/:subid/99'});
|
||||
scope.$eval();
|
||||
|
||||
$location.hash = '/foo/id3?subid=sid1&ignored=true';
|
||||
$location.hash = '/foo/id3/eId?subid=sid1&appended=true';
|
||||
scope.$eval(); //triggers initial route change - match the redirect route
|
||||
$browser.defer.flush(); //triger route change - match the route we redirected to
|
||||
|
||||
expect($location.hash).toBe('/bar/id3/sid1/99');
|
||||
expect($location.hash).toBe('/bar/id3/sid1/99?appended=true&extra=eId');
|
||||
expect($route.current.template).toBe('bar.html');
|
||||
});
|
||||
|
||||
it('should allow custom redirectTo function to be used', function() {
|
||||
var scope = angular.scope(),
|
||||
$location = scope.$service('$location'),
|
||||
$browser = scope.$service('$browser'),
|
||||
$route = scope.$service('$route');
|
||||
|
||||
$route.when('/bar/:id/:subid/:subsubid', {template: 'bar.html'});
|
||||
$route.when('/foo/:id',
|
||||
{redirectTo: customRedirectFn});
|
||||
scope.$eval();
|
||||
|
||||
$location.hash = '/foo/id3?subid=sid1&appended=true';
|
||||
scope.$eval(); //triggers initial route change - match the redirect route
|
||||
$browser.defer.flush(); //triger route change - match the route we redirected to
|
||||
|
||||
expect($location.hash).toBe('custom');
|
||||
|
||||
function customRedirectFn(routePathParams, hash, hashPath, hashSearch) {
|
||||
expect(routePathParams).toEqual({id: 'id3'});
|
||||
expect(hash).toEqual($location.hash);
|
||||
expect(hashPath).toEqual($location.hashPath);
|
||||
expect(hashSearch).toEqual($location.hashSearch);
|
||||
return 'custom';
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue