mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +00:00
feat($route): add events before/after route change
BREAKING CHANGE * removing `onChange` FEATURE * adding three events: $beforeRouteChange, $afterRouteChange, $routeReload
This commit is contained in:
parent
08d09ecbaa
commit
ad3cc16eef
10 changed files with 290 additions and 136 deletions
1
Rakefile
1
Rakefile
|
|
@ -27,6 +27,7 @@ ANGULAR = [
|
|||
'src/service/log.js',
|
||||
'src/service/resource.js',
|
||||
'src/service/route.js',
|
||||
'src/service/routeParams.js',
|
||||
'src/service/window.js',
|
||||
'src/service/xhr.bulk.js',
|
||||
'src/service/xhr.cache.js',
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ load:
|
|||
- src/service/log.js
|
||||
- src/service/resource.js
|
||||
- src/service/route.js
|
||||
- src/service/routeParams.js
|
||||
- src/service/window.js
|
||||
- src/service/xhr.bulk.js
|
||||
- src/service/xhr.cache.js
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ load:
|
|||
- src/service/log.js
|
||||
- src/service/resource.js
|
||||
- src/service/route.js
|
||||
- src/service/routeParams.js
|
||||
- src/service/updateView.js
|
||||
- src/service/window.js
|
||||
- src/service/xhr.bulk.js
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ load:
|
|||
- src/service/log.js
|
||||
- src/service/resource.js
|
||||
- src/service/route.js
|
||||
- src/service/routeParams.js
|
||||
- src/service/window.js
|
||||
- src/service/xhr.bulk.js
|
||||
- src/service/xhr.cache.js
|
||||
|
|
|
|||
1
src/angular-bootstrap.js
vendored
1
src/angular-bootstrap.js
vendored
|
|
@ -114,6 +114,7 @@
|
|||
'service/log.js',
|
||||
'service/resource.js',
|
||||
'service/route.js',
|
||||
'service/routeParams.js',
|
||||
'service/window.js',
|
||||
'service/xhr.bulk.js',
|
||||
'service/xhr.cache.js',
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
* @ngdoc service
|
||||
* @name angular.service.$route
|
||||
* @requires $location
|
||||
* @requires $routeParams
|
||||
*
|
||||
* @property {Object} current Reference to the current route definition.
|
||||
* @property {Array.<Object>} routes Array of all configured routes.
|
||||
|
|
@ -14,7 +15,7 @@
|
|||
* 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}
|
||||
* widget.
|
||||
* widget and the {@link angular.service.$routeParams $routeParams} service.
|
||||
*
|
||||
* @example
|
||||
This example shows how changing the URL hash causes the <tt>$route</tt>
|
||||
|
|
@ -24,23 +25,23 @@
|
|||
<doc:example>
|
||||
<doc:source jsfiddle="false">
|
||||
<script>
|
||||
function MainCntl($route, $location) {
|
||||
function MainCntl($route, $routeParams, $location) {
|
||||
this.$route = $route;
|
||||
this.$location = $location;
|
||||
this.$routeParams = $routeParams;
|
||||
|
||||
$route.when('/Book/:bookId', {template: 'examples/book.html', controller: BookCntl});
|
||||
$route.when('/Book/:bookId/ch/:chapterId', {template: 'examples/chapter.html', controller: ChapterCntl});
|
||||
$route.onChange(function() {
|
||||
$route.current.scope.params = $route.current.params;
|
||||
});
|
||||
}
|
||||
|
||||
function BookCntl() {
|
||||
function BookCntl($routeParams) {
|
||||
this.name = "BookCntl";
|
||||
this.params = $routeParams;
|
||||
}
|
||||
|
||||
function ChapterCntl() {
|
||||
function ChapterCntl($routeParams) {
|
||||
this.name = "ChapterCntl";
|
||||
this.params = $routeParams;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -54,6 +55,7 @@
|
|||
<pre>$route.current.template = {{$route.current.template}}</pre>
|
||||
<pre>$route.current.params = {{$route.current.params}}</pre>
|
||||
<pre>$route.current.scope.name = {{$route.current.scope.name}}</pre>
|
||||
<pre>$routeParams = {{$routeParams}}</pre>
|
||||
<hr />
|
||||
<ng:view></ng:view>
|
||||
</div>
|
||||
|
|
@ -62,34 +64,66 @@
|
|||
</doc:scenario>
|
||||
</doc:example>
|
||||
*/
|
||||
angularServiceInject('$route', function($location) {
|
||||
angularServiceInject('$route', function($location, $routeParams) {
|
||||
/**
|
||||
* @workInProgress
|
||||
* @ngdoc event
|
||||
* @name angular.service.$route#$beforeRouteChange
|
||||
* @eventOf angular.service.$route
|
||||
* @eventType Broadcast on root scope
|
||||
* @description
|
||||
* Broadcasted before a route change.
|
||||
*
|
||||
* @param {Route} next Future route information.
|
||||
* @param {Route} current Current route information.
|
||||
*
|
||||
* The `Route` object extends the route definition with the following properties.
|
||||
*
|
||||
* * `scope` - The instance of the route controller.
|
||||
* * `params` - The current {@link angular.service.$routeParams params}.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @workInProgress
|
||||
* @ngdoc event
|
||||
* @name angular.service.$route#$afterRouteChange
|
||||
* @eventOf angular.service.$route
|
||||
* @eventType Broadcast on root scope
|
||||
* @description
|
||||
* Broadcasted after a route change.
|
||||
*
|
||||
* @param {Route} current Current route information.
|
||||
* @param {Route} previous Previous route information.
|
||||
*
|
||||
* The `Route` object extends the route definition with the following properties.
|
||||
*
|
||||
* * `scope` - The instance of the route controller.
|
||||
* * `params` - The current {@link angular.service.$routeParams params}.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @workInProgress
|
||||
* @ngdoc event
|
||||
* @name angular.service.$route#$routeUpdate
|
||||
* @eventOf angular.service.$route
|
||||
* @eventType Emit on the current route scope.
|
||||
* @description
|
||||
*
|
||||
* The `reloadOnSearch` property has been set to false, and we are reusing the same
|
||||
* instance of the Controller.
|
||||
*/
|
||||
|
||||
var routes = {},
|
||||
onChange = [],
|
||||
matcher = switchRouteMatcher,
|
||||
parentScope = this,
|
||||
rootScope = this,
|
||||
dirty = 0,
|
||||
lastHashPath,
|
||||
lastRouteParams,
|
||||
allowReload = true,
|
||||
$route = {
|
||||
routes: routes,
|
||||
|
||||
/**
|
||||
* @workInProgress
|
||||
* @ngdoc method
|
||||
* @name angular.service.$route#onChange
|
||||
* @methodOf angular.service.$route
|
||||
*
|
||||
* @param {function()} fn Function that will be called when `$route.current` changes.
|
||||
* @returns {function()} The registered function.
|
||||
*
|
||||
* @description
|
||||
* Register a handler function that will be called when route changes
|
||||
*/
|
||||
onChange: function(fn) {
|
||||
onChange.push(fn);
|
||||
return fn;
|
||||
},
|
||||
|
||||
/**
|
||||
* @workInProgress
|
||||
* @ngdoc method
|
||||
|
|
@ -114,7 +148,7 @@ angularServiceInject('$route', function($location) {
|
|||
* @methodOf angular.service.$route
|
||||
*
|
||||
* @param {string} path Route path (matched against `$location.hash`)
|
||||
* @param {Object} params Mapping information to be assigned to `$route.current` on route
|
||||
* @param {Object} route Mapping information to be assigned to `$route.current` on route
|
||||
* match.
|
||||
*
|
||||
* Object properties:
|
||||
|
|
@ -139,14 +173,15 @@ angularServiceInject('$route', function($location) {
|
|||
* to update `$location.hash`.
|
||||
*
|
||||
* - `[reloadOnSearch=true]` - {boolean=} - reload route when $location.hashSearch
|
||||
* changes. If this option is disabled, you should set up a $watch to be notified of
|
||||
* param (hashSearch) changes as follows:
|
||||
* changes.
|
||||
*
|
||||
* function MyCtrl($route) {
|
||||
* this.$watch(function() {
|
||||
* return $route.current.params;
|
||||
* }, function(scope, params) {
|
||||
* //do stuff with params
|
||||
* If the option is set to false and url in the browser changes, then
|
||||
* $routeUpdate event is emited on the current route scope. You can use this event to
|
||||
* react to {@link angular.service.$routeParams} changes:
|
||||
*
|
||||
* function MyCtrl($route, $routeParams) {
|
||||
* this.$on('$routeUpdate', function() {
|
||||
* // do stuff with $routeParams
|
||||
* });
|
||||
* }
|
||||
*
|
||||
|
|
@ -155,13 +190,13 @@ angularServiceInject('$route', function($location) {
|
|||
* @description
|
||||
* Adds a new route definition to the `$route` service.
|
||||
*/
|
||||
when:function (path, params) {
|
||||
when:function (path, route) {
|
||||
if (isUndefined(path)) return routes; //TODO(im): remove - not needed!
|
||||
var route = routes[path];
|
||||
if (!route) route = routes[path] = {reloadOnSearch: true};
|
||||
if (params) extend(route, params); //TODO(im): what the heck? merge two route definitions?
|
||||
var routeDef = routes[path];
|
||||
if (!routeDef) routeDef = routes[path] = {reloadOnSearch: true};
|
||||
if (route) extend(routeDef, route); //TODO(im): what the heck? merge two route definitions?
|
||||
dirty++;
|
||||
return route;
|
||||
return routeDef;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -192,10 +227,18 @@ angularServiceInject('$route', function($location) {
|
|||
*/
|
||||
reload: function() {
|
||||
dirty++;
|
||||
allowReload = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.$watch(function(){ return dirty + $location.hash; }, updateRoute);
|
||||
|
||||
return $route;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
function switchRouteMatcher(on, when, dstName) {
|
||||
var regex = '^' + when.replace(/[\.\\\(\)\^\$]/g, "\$1") + '$',
|
||||
params = [],
|
||||
|
|
@ -219,79 +262,72 @@ angularServiceInject('$route', function($location) {
|
|||
return match ? dst : null;
|
||||
}
|
||||
|
||||
|
||||
function updateRoute(){
|
||||
var selectedRoute, pathParams, segmentMatch, key, redir;
|
||||
var next = parseRoute(),
|
||||
last = $route.current;
|
||||
|
||||
if ($route.current) {
|
||||
if (!$route.current.reloadOnSearch && (lastHashPath == $location.hashPath)) {
|
||||
$route.current.params = extend($location.hashSearch, lastRouteParams);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($route.current.scope) {
|
||||
$route.current.scope.$destroy();
|
||||
}
|
||||
}
|
||||
|
||||
lastHashPath = $location.hashPath;
|
||||
$route.current = null;
|
||||
// Match a route
|
||||
forEach(routes, function(rParams, rPath) {
|
||||
if (!pathParams) {
|
||||
if ((pathParams = matcher($location.hashPath, rPath))) {
|
||||
selectedRoute = rParams;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// No route matched; fallback to "otherwise" route
|
||||
selectedRoute = selectedRoute || routes[null];
|
||||
|
||||
if(selectedRoute) {
|
||||
if (selectedRoute.redirectTo) {
|
||||
if (isString(selectedRoute.redirectTo)) {
|
||||
// interpolate the redirectTo string
|
||||
redir = {hashPath: '',
|
||||
hashSearch: extend({}, $location.hashSearch, pathParams)};
|
||||
|
||||
forEach(selectedRoute.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];
|
||||
}
|
||||
});
|
||||
if (next && last && next.$route === last.$route
|
||||
&& equals(next.pathParams, last.pathParams) && !next.reloadOnSearch && allowReload) {
|
||||
$route.current = next;
|
||||
copy(next.params, $routeParams);
|
||||
last.scope && last.scope.$emit('$routeUpdate');
|
||||
} else {
|
||||
allowReload = true;
|
||||
rootScope.$broadcast('$beforeRouteChange', next, last);
|
||||
last && last.scope && last.scope.$destroy();
|
||||
$route.current = next;
|
||||
if (next) {
|
||||
if (next.redirectTo) {
|
||||
$location.update(isString(next.redirectTo)
|
||||
? {hashSearch: next.params, hashPath: interpolate(next.redirectTo, next.params)}
|
||||
: {hash: next.redirectTo(next.pathParams,
|
||||
$location.hash, $location.hashPath, $location.hashSearch)});
|
||||
} else {
|
||||
// call custom redirectTo function
|
||||
redir = {hash: selectedRoute.redirectTo(pathParams, $location.hash, $location.hashPath,
|
||||
$location.hashSearch)};
|
||||
copy(next.params, $routeParams);
|
||||
next.scope = parentScope.$new(next.controller);
|
||||
}
|
||||
|
||||
$location.update(redir);
|
||||
return;
|
||||
}
|
||||
|
||||
$route.current = extend({}, selectedRoute);
|
||||
$route.current.params = extend({}, $location.hashSearch, pathParams);
|
||||
lastRouteParams = pathParams;
|
||||
}
|
||||
|
||||
//fire onChange callbacks
|
||||
forEach(onChange, parentScope.$eval, parentScope);
|
||||
|
||||
// Create the scope if we have matched a route
|
||||
if ($route.current) {
|
||||
$route.current.scope = parentScope.$new($route.current.controller);
|
||||
rootScope.$broadcast('$afterRouteChange', next, last);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.$watch(function(){ return dirty + $location.hash; }, updateRoute);
|
||||
/**
|
||||
* @returns the current active route, by matching it against the URL
|
||||
*/
|
||||
function parseRoute(){
|
||||
// Match a route
|
||||
var params, match;
|
||||
forEach(routes, function(route, path) {
|
||||
if (!match && (params = matcher($location.hashPath, path))) {
|
||||
match = inherit(route, {
|
||||
params: extend({}, $location.hashSearch, params),
|
||||
pathParams: params});
|
||||
match.$route = route;
|
||||
}
|
||||
});
|
||||
// No route matched; fallback to "otherwise" route
|
||||
return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}});
|
||||
}
|
||||
|
||||
return $route;
|
||||
}, ['$location']);
|
||||
/**
|
||||
* @returns interpolation of the redirect path with the parametrs
|
||||
*/
|
||||
function interpolate(string, params) {
|
||||
var result = [];
|
||||
forEach((string||'').split(':'), function(segment, i) {
|
||||
if (i == 0) {
|
||||
result.push(segment);
|
||||
} else {
|
||||
var segmentMatch = segment.match(/(\w+)(.*)/);
|
||||
var key = segmentMatch[1];
|
||||
result.push(params[key]);
|
||||
result.push(segmentMatch[2] || '');
|
||||
delete params[key];
|
||||
}
|
||||
});
|
||||
return result.join('');
|
||||
}
|
||||
|
||||
|
||||
}, ['$location', '$routeParams']);
|
||||
|
|
|
|||
31
src/service/routeParams.js
Normal file
31
src/service/routeParams.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @workInProgress
|
||||
* @ngdoc service
|
||||
* @name angular.service.$routeParams
|
||||
* @requires $route
|
||||
*
|
||||
* @description
|
||||
* Current set of route parameters. The route parameters are a combination of the
|
||||
* {@link angular.service.$location $location} `hashSearch`, and `path`. The `path` parameters
|
||||
* are extracted when the {@link angular.service.$route $route} path is matched.
|
||||
*
|
||||
* In case of parameter name collision, `path` params take precedence over `hashSearch` params.
|
||||
*
|
||||
* The service guarantees that the identity of the `$routeParams` object will remain unchanged
|
||||
* (but its properties will likely change) even when a route change occurs.
|
||||
*
|
||||
* @example
|
||||
* <pre>
|
||||
* // Given:
|
||||
* // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
|
||||
* // Route: /Chapter/:chapterId/Section/:sectionId
|
||||
* //
|
||||
* // Then
|
||||
* $routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
|
||||
* </pre>
|
||||
*/
|
||||
angularService('$routeParams', function(){
|
||||
return {};
|
||||
});
|
||||
|
|
@ -1422,10 +1422,9 @@ angularWidget('ng:view', function(element) {
|
|||
var template;
|
||||
var changeCounter = 0;
|
||||
|
||||
$route.onChange(function(){
|
||||
this.$on('$afterRouteChange', function(){
|
||||
changeCounter++;
|
||||
})(); //initialize the state forcefully, it's possible that we missed the initial
|
||||
//$route#onChange already
|
||||
});
|
||||
|
||||
this.$watch(function(){return changeCounter;}, function() {
|
||||
var template = $route.current && $route.current.template;
|
||||
|
|
|
|||
41
test/service/routeParamsSpec.js
Normal file
41
test/service/routeParamsSpec.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
'use strict';
|
||||
|
||||
describe('$routeParams', function(){
|
||||
it('should publish the params into a service', function(){
|
||||
var scope = angular.scope(),
|
||||
$location = scope.$service('$location'),
|
||||
$route = scope.$service('$route'),
|
||||
$routeParams = scope.$service('$routeParams');
|
||||
|
||||
$route.when('/foo');
|
||||
$route.when('/bar/:barId');
|
||||
|
||||
$location.hash = '/foo?a=b';
|
||||
scope.$digest();
|
||||
expect($routeParams).toEqual({a:'b'});
|
||||
|
||||
$location.hash = '/bar/123?x=abc';
|
||||
scope.$digest();
|
||||
expect($routeParams).toEqual({barId:'123', x:'abc'});
|
||||
});
|
||||
|
||||
|
||||
it('should preserve object identity during route reloads', function(){
|
||||
var scope = angular.scope(),
|
||||
$location = scope.$service('$location'),
|
||||
$route = scope.$service('$route'),
|
||||
$routeParams = scope.$service('$routeParams'),
|
||||
firstRouteParams = $routeParams;
|
||||
|
||||
$route.when('/foo');
|
||||
$route.when('/bar/:barId');
|
||||
|
||||
$location.hash = '/foo?a=b';
|
||||
scope.$digest();
|
||||
expect(scope.$service('$routeParams')).toBe(firstRouteParams);
|
||||
|
||||
$location.hash = '/bar/123?x=abc';
|
||||
scope.$digest();
|
||||
expect(scope.$service('$routeParams')).toBe(firstRouteParams);
|
||||
});
|
||||
});
|
||||
|
|
@ -15,37 +15,48 @@ describe('$route', function() {
|
|||
|
||||
it('should route and fire change event', function(){
|
||||
var log = '',
|
||||
$location, $route;
|
||||
$location, $route,
|
||||
lastRoute,
|
||||
nextRoute;
|
||||
|
||||
function BookChapter() {
|
||||
log += '<init>';
|
||||
log += '<init>;';
|
||||
}
|
||||
scope = compile('<div></div>')();
|
||||
$location = scope.$service('$location');
|
||||
$route = scope.$service('$route');
|
||||
$route.when('/Book/:book/Chapter/:chapter', {controller: BookChapter, template:'Chapter.html'});
|
||||
$route.when('/Blank');
|
||||
$route.onChange(function(){
|
||||
log += 'onChange();';
|
||||
scope.$on('$beforeRouteChange', function(event, next, current){
|
||||
log += 'before();';
|
||||
expect(current).toBe($route.current);
|
||||
lastRoute = current;
|
||||
nextRoute = next;
|
||||
});
|
||||
scope.$on('$afterRouteChange', function(event, current, last){
|
||||
log += 'after();';
|
||||
expect(current).toBe($route.current);
|
||||
expect(lastRoute).toBe(last);
|
||||
expect(nextRoute).toBe(current);
|
||||
});
|
||||
|
||||
$location.update('http://server#/Book/Moby/Chapter/Intro?p=123');
|
||||
scope.$digest();
|
||||
expect(log).toEqual('onChange();<init>');
|
||||
expect(log).toEqual('before();<init>;after();');
|
||||
expect($route.current.params).toEqual({book:'Moby', chapter:'Intro', p:'123'});
|
||||
var lastId = $route.current.scope.$id;
|
||||
|
||||
log = '';
|
||||
$location.update('http://server#/Blank?ignore');
|
||||
scope.$digest();
|
||||
expect(log).toEqual('onChange();');
|
||||
expect(log).toEqual('before();after();');
|
||||
expect($route.current.params).toEqual({ignore:true});
|
||||
expect($route.current.scope.$id).not.toEqual(lastId);
|
||||
|
||||
log = '';
|
||||
$location.update('http://server#/NONE');
|
||||
scope.$digest();
|
||||
expect(log).toEqual('onChange();');
|
||||
expect(log).toEqual('before();after();');
|
||||
expect($route.current).toEqual(null);
|
||||
|
||||
$route.when('/NONE', {template:'instant update'});
|
||||
|
|
@ -54,15 +65,6 @@ describe('$route', function() {
|
|||
});
|
||||
|
||||
|
||||
it('should return fn registered with onChange()', function() {
|
||||
var scope = angular.scope(),
|
||||
$route = scope.$service('$route'),
|
||||
fn = function() {};
|
||||
|
||||
expect($route.onChange(fn)).toBe(fn);
|
||||
});
|
||||
|
||||
|
||||
it('should allow routes to be defined with just templates without controllers', function() {
|
||||
var scope = angular.scope(),
|
||||
$location = scope.$service('$location'),
|
||||
|
|
@ -70,7 +72,7 @@ describe('$route', function() {
|
|||
onChangeSpy = jasmine.createSpy('onChange');
|
||||
|
||||
$route.when('/foo', {template: 'foo.html'});
|
||||
$route.onChange(onChangeSpy);
|
||||
scope.$on('$beforeRouteChange', onChangeSpy);
|
||||
expect($route.current).toBeUndefined();
|
||||
expect(onChangeSpy).not.toHaveBeenCalled();
|
||||
|
||||
|
|
@ -93,7 +95,7 @@ describe('$route', function() {
|
|||
|
||||
$route.when('/foo', {template: 'foo.html'});
|
||||
$route.otherwise({template: '404.html', controller: NotFoundCtrl});
|
||||
$route.onChange(onChangeSpy);
|
||||
scope.$on('$beforeRouteChange', onChangeSpy);
|
||||
expect($route.current).toBeUndefined();
|
||||
expect(onChangeSpy).not.toHaveBeenCalled();
|
||||
|
||||
|
|
@ -163,7 +165,7 @@ describe('$route', function() {
|
|||
$route.when('/bar', {template: 'bar.html'});
|
||||
$route.when('/baz', {redirectTo: '/bar'});
|
||||
$route.otherwise({template: '404.html'});
|
||||
$route.onChange(onChangeSpy);
|
||||
scope.$on('$beforeRouteChange', onChangeSpy);
|
||||
expect($route.current).toBeUndefined();
|
||||
expect(onChangeSpy).not.toHaveBeenCalled();
|
||||
|
||||
|
|
@ -172,7 +174,8 @@ describe('$route', function() {
|
|||
|
||||
expect($location.hash).toBe('/foo');
|
||||
expect($route.current.template).toBe('foo.html');
|
||||
expect(onChangeSpy.callCount).toBe(1);
|
||||
expect(onChangeSpy.callCount).toBe(2);
|
||||
|
||||
|
||||
onChangeSpy.reset();
|
||||
$location.updateHash('');
|
||||
|
|
@ -181,7 +184,7 @@ describe('$route', function() {
|
|||
|
||||
expect($location.hash).toBe('/foo');
|
||||
expect($route.current.template).toBe('foo.html');
|
||||
expect(onChangeSpy.callCount).toBe(1);
|
||||
expect(onChangeSpy.callCount).toBe(2);
|
||||
|
||||
onChangeSpy.reset();
|
||||
$location.updateHash('/baz');
|
||||
|
|
@ -190,7 +193,7 @@ describe('$route', function() {
|
|||
|
||||
expect($location.hash).toBe('/bar');
|
||||
expect($route.current.template).toBe('bar.html');
|
||||
expect(onChangeSpy.callCount).toBe(1);
|
||||
expect(onChangeSpy.callCount).toBe(2);
|
||||
});
|
||||
|
||||
|
||||
|
|
@ -267,10 +270,11 @@ describe('$route', function() {
|
|||
var scope = angular.scope(),
|
||||
$location = scope.$service('$location'),
|
||||
$route = scope.$service('$route'),
|
||||
$rouetParams = scope.$service('$routeParams'),
|
||||
reloaded = jasmine.createSpy('route reload');
|
||||
|
||||
$route.when('/foo', {controller: FooCtrl});
|
||||
$route.onChange(reloaded);
|
||||
scope.$on('$beforeRouteChange', reloaded);
|
||||
|
||||
function FooCtrl() {
|
||||
reloaded();
|
||||
|
|
@ -279,12 +283,14 @@ describe('$route', function() {
|
|||
$location.updateHash('/foo');
|
||||
scope.$digest();
|
||||
expect(reloaded).toHaveBeenCalled();
|
||||
expect($rouetParams).toEqual({});
|
||||
reloaded.reset();
|
||||
|
||||
// trigger reload
|
||||
$location.hashSearch.foo = 'bar';
|
||||
scope.$digest();
|
||||
expect(reloaded).toHaveBeenCalled();
|
||||
expect($rouetParams).toEqual({foo:'bar'});
|
||||
});
|
||||
|
||||
|
||||
|
|
@ -293,13 +299,15 @@ describe('$route', function() {
|
|||
var scope = angular.scope(),
|
||||
$location = scope.$service('$location'),
|
||||
$route = scope.$service('$route'),
|
||||
reloaded = jasmine.createSpy('route reload');
|
||||
reloaded = jasmine.createSpy('route reload'),
|
||||
routeUpdateEvent = jasmine.createSpy('route reload');
|
||||
|
||||
$route.when('/foo', {controller: FooCtrl, reloadOnSearch: false});
|
||||
$route.onChange(reloaded);
|
||||
scope.$on('$beforeRouteChange', reloaded);
|
||||
|
||||
function FooCtrl() {
|
||||
reloaded();
|
||||
this.$on('$routeUpdate', routeUpdateEvent);
|
||||
}
|
||||
|
||||
expect(reloaded).not.toHaveBeenCalled();
|
||||
|
|
@ -307,12 +315,14 @@ describe('$route', function() {
|
|||
$location.updateHash('/foo');
|
||||
scope.$digest();
|
||||
expect(reloaded).toHaveBeenCalled();
|
||||
expect(routeUpdateEvent).not.toHaveBeenCalled();
|
||||
reloaded.reset();
|
||||
|
||||
// don't trigger reload
|
||||
$location.hashSearch.foo = 'bar';
|
||||
scope.$digest();
|
||||
expect(reloaded).not.toHaveBeenCalled();
|
||||
expect(routeUpdateEvent).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
||||
|
|
@ -324,7 +334,7 @@ describe('$route', function() {
|
|||
onRouteChange = jasmine.createSpy('onRouteChange');
|
||||
|
||||
$route.when('/foo/:fooId', {controller: FooCtrl, reloadOnSearch: false});
|
||||
$route.onChange(onRouteChange);
|
||||
scope.$on('$beforeRouteChange', onRouteChange);
|
||||
|
||||
function FooCtrl() {
|
||||
reloaded();
|
||||
|
|
@ -394,5 +404,37 @@ describe('$route', function() {
|
|||
scope.$digest();
|
||||
expect(routeParams).toHaveBeenCalledWith({barId: '123', foo: 'bar'});
|
||||
});
|
||||
|
||||
|
||||
describe('reload', function(){
|
||||
|
||||
it('should reload even if reloadOnSearch is false', function(){
|
||||
var scope = angular.scope(),
|
||||
$location = scope.$service('$location'),
|
||||
$route = scope.$service('$route'),
|
||||
$routeParams = scope.$service('$routeParams'),
|
||||
count = 0;
|
||||
|
||||
$route.when('/bar/:barId', {controller: FooCtrl, reloadOnSearch: false});
|
||||
|
||||
function FooCtrl() { count ++; }
|
||||
|
||||
$location.updateHash('/bar/123');
|
||||
scope.$digest();
|
||||
expect($routeParams).toEqual({barId:'123'});
|
||||
expect(count).toEqual(1);
|
||||
|
||||
$location.hash = '/bar/123?a=b';
|
||||
scope.$digest();
|
||||
expect($routeParams).toEqual({barId:'123', a:'b'});
|
||||
expect(count).toEqual(1);
|
||||
|
||||
$route.reload();
|
||||
scope.$digest();
|
||||
expect($routeParams).toEqual({barId:'123', a:'b'});
|
||||
expect(count).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue