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

Commit 60069e6

Browse files
committed
feat($route): add support for the reloadOnUrl configuration option
Enables users to specify that a particular route should not be reloaded after a URL change (including a change in `$location.path()`), if the new URL maps to the same route. The default behavior is still to always load the matched route when any part of the URL changes. Related to #1699, #5860, #14999 (potentially closing the first two). Fixes #7925 Closes #15002
1 parent 84d80be commit 60069e6

File tree

2 files changed

+421
-53
lines changed

2 files changed

+421
-53
lines changed

src/ngRoute/route.js

+43-7
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,22 @@ function $RouteProvider() {
183183
* `redirectTo` takes precedence over `resolveRedirectTo`, so specifying both on the same
184184
* route definition, will cause the latter to be ignored.
185185
*
186+
* - `[reloadOnUrl=true]` - `{boolean=}` - reload route when any part of the URL changes
187+
* (inluding the path) even if the new URL maps to the same route.
188+
*
189+
* If the option is set to `false` and the URL in the browser changes, but the new URL maps
190+
* to the same route, then a `$routeUpdate` event is broadcasted on the root scope (without
191+
* reloading the route).
192+
*
186193
* - `[reloadOnSearch=true]` - `{boolean=}` - reload route when only `$location.search()`
187194
* or `$location.hash()` changes.
188195
*
189-
* If the option is set to `false` and url in the browser changes, then
190-
* `$routeUpdate` event is broadcasted on the root scope.
196+
* If the option is set to `false` and the URL in the browser changes, then a `$routeUpdate`
197+
* event is broadcasted on the root scope (without reloading the route).
198+
*
199+
* <div class="alert alert-warning">
200+
* **Note:** This option has no effect if `reloadOnUrl` is set to `false`.
201+
* </div>
191202
*
192203
* - `[caseInsensitiveMatch=false]` - `{boolean=}` - match routes without being case sensitive
193204
*
@@ -202,6 +213,9 @@ function $RouteProvider() {
202213
this.when = function(path, route) {
203214
//copy original route object to preserve params inherited from proto chain
204215
var routeCopy = shallowCopy(route);
216+
if (angular.isUndefined(routeCopy.reloadOnUrl)) {
217+
routeCopy.reloadOnUrl = true;
218+
}
205219
if (angular.isUndefined(routeCopy.reloadOnSearch)) {
206220
routeCopy.reloadOnSearch = true;
207221
}
@@ -544,8 +558,9 @@ function $RouteProvider() {
544558
* @name $route#$routeUpdate
545559
* @eventType broadcast on root scope
546560
* @description
547-
* The `reloadOnSearch` property has been set to false, and we are reusing the same
548-
* instance of the Controller.
561+
* Broadcasted if the same instance of a route (including template, controller instance,
562+
* resolved dependencies, etc.) is being reused. This can happen if either `reloadOnSearch` or
563+
* `reloadOnUrl` has been set to `false`.
549564
*
550565
* @param {Object} angularEvent Synthetic event object
551566
* @param {Route} current Current/previous route information.
@@ -653,9 +668,7 @@ function $RouteProvider() {
653668
var lastRoute = $route.current;
654669

655670
preparedRoute = parseRoute();
656-
preparedRouteIsUpdateOnly = preparedRoute && lastRoute && preparedRoute.$$route === lastRoute.$$route
657-
&& angular.equals(preparedRoute.pathParams, lastRoute.pathParams)
658-
&& !preparedRoute.reloadOnSearch && !forceReload;
671+
preparedRouteIsUpdateOnly = isNavigationUpdateOnly(preparedRoute, lastRoute);
659672

660673
if (!preparedRouteIsUpdateOnly && (lastRoute || preparedRoute)) {
661674
if ($rootScope.$broadcast('$routeChangeStart', preparedRoute, lastRoute).defaultPrevented) {
@@ -835,6 +848,29 @@ function $RouteProvider() {
835848
return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}});
836849
}
837850

851+
/**
852+
* @param {Object} newRoute - The new route configuration (as returned by `parseRoute()`).
853+
* @param {Object} oldRoute - The previous route configuration (as returned by `parseRoute()`).
854+
* @returns {boolean} Whether this is an "update-only" navigation, i.e. the URL maps to the same
855+
* route and it can be reused (based on the config and the type of change).
856+
*/
857+
function isNavigationUpdateOnly(newRoute, oldRoute) {
858+
// IF this is not a forced reload
859+
return !forceReload
860+
// AND both `newRoute`/`oldRoute` are defined
861+
&& newRoute && oldRoute
862+
// AND they map to the same Route Definition Object
863+
&& (newRoute.$$route === oldRoute.$$route)
864+
// AND `reloadOnUrl` is disabled
865+
&& (!newRoute.reloadOnUrl
866+
// OR `reloadOnSearch` is disabled
867+
|| (!newRoute.reloadOnSearch
868+
// AND both routes have the same path params
869+
&& angular.equals(newRoute.pathParams, oldRoute.pathParams)
870+
)
871+
);
872+
}
873+
838874
/**
839875
* @returns {string} interpolation of the redirect path with the parameters
840876
*/

0 commit comments

Comments
 (0)