Skip to content

Instantly share code, notes, and snippets.

@stakach
Last active May 13, 2018 08:12
Show Gist options
  • Save stakach/5897621 to your computer and use it in GitHub Desktop.
Save stakach/5897621 to your computer and use it in GitHub Desktop.
Augments AngularJS $route provider with route naming.
(function(angular) {
'use strict';
/*
Usage:
-----
FILE --app.js--
angular.module('RouteExample')
.config(['$namedRouteProvider', function ($routeProvider) {
$routeProvider
.when('/', {
name: 'login',
templateUrl: 'views/login.html',
controller: 'LoginCtrl'
})
.when('/:client', {
name: 'home',
templateUrl: 'views/dashboard.html',
controller: 'DashboardCtrl'
})
.when('/:client/profile', {
name: 'profile',
templateUrl: 'views/profile.html',
controller: 'ProfileCtrl'
})
.otherwise({
redirectTo: '/'
});
}]).
controller('AppCtrl', ['$scope', '$route', function($scope, $route) {
// Some global helper functions for routing
$scope.goto = function(page, optionalParams) {
$route.to[page](optionalParams);
};
$scope.login = function() {
$route.to.login();
};
}]);
FILE --dashboard.html--
<!--
note that we are at /:client/ in this view
To goto the profile page we need to goto /:client/profile maintaining our client param
This named route provider does that for you, maintaining any existing params in the new route
whilst also allowing new params to be passed in as required or to override existing params
-->
<span ng-click="login()">Logout</span>
<nav>
<ul>
<li ng-click="goto('home')" ng-class="{active: $route.current.name == 'home'}">Dashboard</li>
<li ng-click="goto('profile')" ng-class="{active: $route.current.name == 'profile'}">My Profile</li>
</ul>
</nav>
*/
angular.module('Core')
.provider('$namedRoute', ['$routeProvider', function($routeProvider) {
var namedRoutes = {},
paramMatcher = /(?:\:)(.*?)(?:(\/|$)\/?)/gm;
this.when = function(path, route) {
if (route.name) {
var altPath = path,
matches = altPath.match(paramMatcher) || [],
param,
i;
// this converts paths '/:param1/:param2' to '/{{param1}}/{{param2}}/'
for (i = 0; param = matches[i]; i += 1) { // this will break on undefined
altPath = altPath.replace(param, '{{' + param.replace(/\:|\//gm, '') + '}}/');
}
namedRoutes[route.name] = altPath;
}
// Update the actual route provider
$routeProvider.when(path, route);
return this;
};
this.otherwise = $routeProvider.otherwise;
this.$get = ['$interpolate', '$route', '$routeParams', '$location', function($interpolate, $route, $routeParams, $location) {
// Create an interpolation function for the routes
angular.forEach(namedRoutes, function(route, name) {
namedRoutes[name] = $interpolate(route);
});
// Update the route object with named routes
$route.to = {};
// For all the named routes, allow automatic param injection with override based on the existing context
angular.forEach(namedRoutes, function(route, name) {
$route.to[name] = function(params) {
params = angular.extend({}, $routeParams, params);
$location.path(route(params));
};
});
// We just return the original route service
return $route;
}];
}])
.run(['$namedRoute', function() {
// inject $namedRoute into $route
}]);
}(this.angular));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment