From 2496a290a9e347be1547382a37d17c3adde12588 Mon Sep 17 00:00:00 2001 From: Dave Geddes Date: Sun, 29 Sep 2013 00:55:32 -0600 Subject: [PATCH] feat(ngRoute): expose parseRoute as public method `$route.parseRoute` should be public, allowing you to determine which route a given path will resolve to. This lets you store meta data in your routes config, and take action (e.g. cancel route) before the route changes. Example use case: before navigating, check if the route's feature is feature-switched on or off. If off, cancel the route and display a "feature disabled" popup. Add a `feature` property to each route: ```js $routeProvider.when('/profile', feature: 'profile', template: 'profile.html', controller: 'ProfileCtrl' }); ``` In a main controller, cancel routing and display popup when a route's feature is disabled. ```js $scope.$on('$locationChangeStart', function(e) { // determine the route the user is trying to navigate to var nextRoute = $route.parseRoute($location.path()); // get the feature metadata from the route var nextFeature = nextRoute.$$route.feature; // check if the feature is set to disabled using an app-specific // service var status = AppFeatures.status(nextFeature); if (status === 'disabled'){ // cancel the route e.preventDefault(); // display popup $scope.showFeatureDisabledModal(); } }); ``` Making `parseRoute` public gives your application a lot of flexibility and control over routing. --- src/ngRoute/route.js | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/ngRoute/route.js b/src/ngRoute/route.js index 4000f413ecf1..ef8ef0b3cc27 100644 --- a/src/ngRoute/route.js +++ b/src/ngRoute/route.js @@ -436,6 +436,29 @@ function $RouteProvider(){ reload: function() { forceReload = true; $rootScope.$evalAsync(updateRoute); + }, + + /** + * @ngdoc method + * @name $route#parseRoute + * @return {Object} the matching route + * + * @description + * Finds the route that matches the provided path. + */ + parseRoute: function(r) { + // Match a route + var params, match; + angular.forEach(routes, function(route, path) { + if (!match && (params = switchRouteMatcher(r, route))) { + match = inherit(route, { + params: angular.extend({}, $location.search(), params), + pathParams: params}); + match.$$route = route; + } + }); + // No route matched; fallback to "otherwise" route + return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}}); } }; @@ -480,7 +503,7 @@ function $RouteProvider(){ } function updateRoute() { - var next = parseRoute(), + var next = $route.parseRoute($location.path()), last = $route.current; if (next && last && next.$$route === last.$$route @@ -554,25 +577,6 @@ function $RouteProvider(){ } } - - /** - * @returns {Object} the current active route, by matching it against the URL - */ - function parseRoute() { - // Match a route - var params, match; - angular.forEach(routes, function(route, path) { - if (!match && (params = switchRouteMatcher($location.path(), route))) { - match = inherit(route, { - params: angular.extend({}, $location.search(), params), - pathParams: params}); - match.$$route = route; - } - }); - // No route matched; fallback to "otherwise" route - return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}}); - } - /** * @returns {string} interpolation of the redirect path with the parameters */