Introduction
If we are developing a large web application, then normally, we use SiteMap to let the user know where they are at the current moment. It was quite easy in ASP.NET, etc. as it was having sitemap control builtin. But if we are developing SPA application using AngularJS, then we don't have some builtin control (as per my knowledge as I Googled but was not able to find :( ) . So if you are willing to have SiteMap in SPA using AngularJS on the fly, the quick solution/trick explain in this tip will help you.
Background
I assume that you already know ngRoute
module in AngularJS. ngRoute
module provides routing and deeplinking services and directives for Angular apps. If you would like to read in detail, then here is the link. And I am using RequireJS for modular code/loading JS files. If you would like to learn about it, here is the link.
Using the Code
In order to get SiteMap working on the fly in SPA apps using AngularJS, I have followed one standard to create the path for the template/view. Say, I have the following menu in my app:
Then my $routeProvider
will be configured as below:
$routeProvider
.when('/home', {
templateUrl: 'app/commonModule/views/home.html',
controller: 'homeController',
title: "Home",
controllerAs : 'vm'
}).
when('/menuOne/subMenuOne/pageOne', {
templateUrl: 'app/module1/views/page1.html',
controller: 'page11Controller',
title: "Page One - Module One",
controllerAs: 'vm'
}).
when('/menuOne/subMenuTwo/pageTwo', {
templateUrl: 'app/module1/views/page2.html',
controller: 'page12Controller',
title: "Page Two - Module One",
controllerAs: 'vm'
}).
and so on...
As you can see from the above Menu image and route config, I have followed the route path as Menu, starting from parent (Menu
) to child (page
) by separating it by "/
", i.e. '/menuOne/subMenuOne/pageOne'. And on the $routeChangeSuccess
, splitting it by "/
" and using some regular expression to uncamel the case (I have followed the camel case for path) and storing it in $rootScope.SiteMap
as you can see in the below code blocks:
app.run(['$rootScope', '$location', '$routeParams',
function ($rootScope, $location, $routeParams) {
$rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
$rootScope.title = current.title;
$rootScope.SiteMap = GetSiteMap();
highlightMenubar();
});
function GetSiteMap() {
var paramsLenght = Object.keys($routeParams).length;
var paths = $location.path().split('/');
var actualPathsLenght = paths.length - paramsLenght;
var formatedPath = [];
for (var i = 1; i < actualPathsLenght; i++) {
formatedPath[i - 1] = unCamelCase(paths[i]);
}
return formatedPath;
};
Now we have Path
details for the current page, we just need to show it in UI. We could use the below given code to render the same:
<ol class="breadcrumb">
<li class="active"> </li>
<li class="active" data-ng-repeat="sitePath in SiteMap"> {{sitePath}}</li>
</ol>
And as we can see in the below screenshot, finally our site map is rendered on UI (shown at the right top corner in green rectangle) for the selected page (shown in left side nav
menu in red rectangle). At the same time, let me thank Mr. Alexander Pierce for his apps Layout/CSS what I have used here to design the sample project.
Note: All the code used here could be found in the sample project app/aap.js and index.html. For the sake of simplicity, I have put all the code in aap.js, we could create some service or separate controller for the same!
Page Title: One more thing you could notice in the above screenshot (in the middle of screen, red rectangle) is Page Title. To make it standard at one place in the entire site, I have created one extra property in $routeProvider
and given the specific value for the particular page. And on the $routeChangeSuccess
getting the value and storing it in $rootScope.title
and rendering in UI (code : data-ng-bind="title"
).
Points of Interest
Just by following some standard/naming conventions and without having any dependency, we are able to show SiteMap with the power of AngularJS.
History
- 27th August, 2015: Initial version