feat($route): add reloadOnSearch route param to avoid reloads

In order to avoid unnecesary route reloads when just hashSearch part
of the url changes, it is now possible to disable this behavior by
setting reloadOnSearch param of the route declaration to false.

Closes #354
This commit is contained in:
Igor Minar
2011-08-15 08:34:11 -07:00
parent 6114c8f504
commit dc0b0c77c7
2 changed files with 165 additions and 6 deletions

View File

@@ -68,6 +68,8 @@ angularServiceInject('$route', function($location) {
matcher = switchRouteMatcher,
parentScope = this,
dirty = 0,
lastHashPath,
lastRouteParams,
$route = {
routes: routes,
@@ -136,6 +138,18 @@ angularServiceInject('$route', function($location) {
* The custom `redirectTo` function is expected to return a string which will be used
* 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:
*
* function MyCtrl($route) {
* this.$watch(function() {
* return $route.current.params;
* }, function(scope, params) {
* //do stuff with params
* });
* }
*
* @returns {Object} route object
*
* @description
@@ -144,8 +158,8 @@ angularServiceInject('$route', function($location) {
when:function (path, params) {
if (isUndefined(path)) return routes; //TODO(im): remove - not needed!
var route = routes[path];
if (!route) route = routes[path] = {};
if (params) extend(route, params);
if (!route) route = routes[path] = {reloadOnSearch: true};
if (params) extend(route, params); //TODO(im): what the heck? merge two route definitions?
dirty++;
return route;
},
@@ -209,9 +223,18 @@ angularServiceInject('$route', function($location) {
function updateRoute(){
var selectedRoute, pathParams, segmentMatch, key, redir;
if ($route.current && $route.current.scope) {
$route.current.scope.$destroy();
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) {
@@ -255,19 +278,20 @@ angularServiceInject('$route', function($location) {
$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 mtched a route
// Create the scope if we have matched a route
if ($route.current) {
$route.current.scope = parentScope.$new($route.current.controller);
}
}
this.$watch(function(){return dirty + $location.hash;}, updateRoute);
this.$watch(function(){ return dirty + $location.hash; }, updateRoute);
return $route;
}, ['$location']);