aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Rakefile1
-rw-r--r--jsTestDriver-jquery.conf1
-rw-r--r--jsTestDriver-perf.conf1
-rw-r--r--jsTestDriver.conf1
-rw-r--r--src/angular-bootstrap.js1
-rw-r--r--src/service/route.js242
-rw-r--r--src/service/routeParams.js31
-rw-r--r--src/widgets.js5
-rw-r--r--test/service/routeParamsSpec.js41
-rw-r--r--test/service/routeSpec.js94
10 files changed, 286 insertions, 132 deletions
diff --git a/Rakefile b/Rakefile
index 1f0f7d25..a9c1ee6c 100644
--- a/Rakefile
+++ b/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',
diff --git a/jsTestDriver-jquery.conf b/jsTestDriver-jquery.conf
index 018e836c..705ade10 100644
--- a/jsTestDriver-jquery.conf
+++ b/jsTestDriver-jquery.conf
@@ -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
diff --git a/jsTestDriver-perf.conf b/jsTestDriver-perf.conf
index a46cbf71..6ddc018e 100644
--- a/jsTestDriver-perf.conf
+++ b/jsTestDriver-perf.conf
@@ -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
diff --git a/jsTestDriver.conf b/jsTestDriver.conf
index b55a387c..24349094 100644
--- a/jsTestDriver.conf
+++ b/jsTestDriver.conf
@@ -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
diff --git a/src/angular-bootstrap.js b/src/angular-bootstrap.js
index fdf07c3e..f88973e0 100644
--- a/src/angular-bootstrap.js
+++ b/src/angular-bootstrap.js
@@ -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',
diff --git a/src/service/route.js b/src/service/route.js
index b7e4814b..523a244a 100644
--- a/src/service/route.js
+++ b/src/service/route.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,37 +64,69 @@
</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
* @name angular.service.$route#parent
* @methodOf angular.service.$route
*
@@ -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.
+ *
+ * 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) {
- * this.$watch(function() {
- * return $route.current.params;
- * }, function(scope, params) {
- * //do stuff with params
+ * 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();
+ 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 {
+ copy(next.params, $routeParams);
+ next.scope = parentScope.$new(next.controller);
+ }
}
+ rootScope.$broadcast('$afterRouteChange', next, last);
}
+ }
+
- lastHashPath = $location.hashPath;
- $route.current = null;
+ /**
+ * @returns the current active route, by matching it against the URL
+ */
+ function parseRoute(){
// Match a route
- forEach(routes, function(rParams, rPath) {
- if (!pathParams) {
- if ((pathParams = matcher($location.hashPath, rPath))) {
- selectedRoute = rParams;
- }
+ 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
- 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];
- }
- });
- } else {
- // call custom redirectTo function
- redir = {hash: selectedRoute.redirectTo(pathParams, $location.hash, $location.hashPath,
- $location.hashSearch)};
- }
+ return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}});
+ }
- $location.update(redir);
- return;
+ /**
+ * @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];
}
-
- $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);
- }
+ });
+ return result.join('');
}
- this.$watch(function(){ return dirty + $location.hash; }, updateRoute);
-
- return $route;
-}, ['$location']);
+}, ['$location', '$routeParams']);
diff --git a/src/service/routeParams.js b/src/service/routeParams.js
new file mode 100644
index 00000000..8a69903f
--- /dev/null
+++ b/src/service/routeParams.js
@@ -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 {};
+});
diff --git a/src/widgets.js b/src/widgets.js
index a1c4c5d6..42e608dd 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -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;
diff --git a/test/service/routeParamsSpec.js b/test/service/routeParamsSpec.js
new file mode 100644
index 00000000..58a37f2e
--- /dev/null
+++ b/test/service/routeParamsSpec.js
@@ -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);
+ });
+});
diff --git a/test/service/routeSpec.js b/test/service/routeSpec.js
index 72c7745c..b1dde915 100644
--- a/test/service/routeSpec.js
+++ b/test/service/routeSpec.js
@@ -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);
+ });
+ });
+
});
});