Introduction
AngularJS Nested routing: Ok, this is my second article on the same subject (ui-router). If you are interested to see my first article you can visit here. Ok, lets move on, with the ui-router nested states. ui-router is very powerful compared with the ng-route which is part of the AngularJS framework. The Ui-router provides the features where we can do the nested routing and named views vice versa. Ok we will see examples for all the types which are there in the ui-router.
Direct to Action
Background
Refer, my previous article to give heads up on the simple routing with ui-router framework, Let us say we have different types of navigations based on the requirement what we get, common navigation like moving from one page to another page is very generic. But there are typical cases where, imgine, you have master page in that we have tabs or menu on click of the menu item we need to show the respective pages.
Fine, let us see an typical navigation..
Reg. this navigation we have already seen in my previous article. Now as per the topic we will see the navigation of nested views.
As per the above screen design, we will be designing our page, to navigate from one page to another page, when clicking on the page-1 we will show the content of the page-1 below, same goes to other pages on click. Hope this is straight forward to proceed. Let us start our code work.
In Action
As per the requirement we will be creating simple html and javascript pages to do this with AngularJS framework. We will be creating Three HTML pages and one Javascript file.
To start with create a empty web application and add Three HTML pages. As shown below. These pages are partial views, which are going to be displayed during the navigation. Also to show the Application tab we will have one more page let us call it as PageTab.html.
So below are the files we need to create.
1. Page1.html
2. Page2.html
3. Page3.html
4. PageTab.html
Note: We will be using the 1.2 version of AngularJS, while i write this article, AngularJS 1.3 was already released.
Page1.html
Create html page with the content shown below.
<div>
<div>
<h1>Page 1 content goes here...</h1>
</div>
</div>
Page2.html
Create html page with the content shown below.
<div>
<div>
<h1>Page 2 content goes here...</h1>
</div>
</div>
Page3.html
Create html page with the content shown below.
<div>
<div>
<h1>Page 3 content goes here...</h1>
</div>
</div>
Now, the navigation tab we will create,
PageTab.html
Create html page with the content shown below.
<div>
<div>
<span style="width:100px">Page-1</span>
<span style="width:100px">Page-2</span>
<span style="width:100px">Page-3</span>
</div>
</div>
This will give the page text side by side, oops i missed to add the hyperlink when the user hover the mouse on the text. Let us do that now.
<div>
<div>
<span style="width:100px"><a href="">Page-1</a></span>
<span style="width:100px"><a href="">Page-2</a></span>
<span style="width:100px"><a href="">Page-3</a></span>
</div>
</div>
The thing is we are not going to point to any hyperlink, just to get the link i had put the href, actually this is just an workaround to get url.
Note, as of now, we have not plugged any angularjs routing or any framework. The thing is whatever as of now we have created those are partial pages only, we need a placeholder / parent page to host this. Let us call that page as Main.html.
We will create that now.
Main.html
Create html page with the content shown below.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-ui-router.js"></script>
<script src="App.js"></script>
</head>
<body data-ng-app="myApp">
<h1>AngularJS Home Page (Ui-router Demonstration)</h1>
<div data-ui-view=""></div>
</body>
<html>
couple of things we are doing in the main page, (i) we have referenced the angularjs framework (ii) we have referenced the ui-router framework. (iii) then the angularjs file App.js (i will talk about this later) (iv) the fourth is the main page content like master content will be displayed and then the placeholder to host the pages.
Now, let us see the App.JS file and the content, we will be delcaring the angularjs module and the route configuration we are going to do in this. On load of the page we will be showing the Main.html with PageTab.html page. Let us code that.
App.js
var myApp = angular.module("myApp", ['ui.router']);
myApp.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.when("", "/PageTab");
$stateProvider
.state("PageTab", {
url: "/PageTab",
templateUrl: "PageTab.html"
})
.state("PageTab.Page1", {
url:"/Page1",
templateUrl: "Page-1.html"
})
.state("PageTab.Page2", {
url:"/Page2",
templateUrl: "Page-2.html"
})
.state("PageTab.Page3", {
url:"/Page3",
templateUrl: "Page3.html"
});
});
Ok, what does it says we will see step by step.
Line-1: The first line, it declares the angularjs module, as well as the ui-router injection into the angularjs main module, all together we are getting the angular module.
var myApp = angular.module("myApp", ['ui.router']);
This is called app module, which will be telling the HTML page this is angularjs enabled page, the content will get interpreted by the angularjs engine.
Line-2: This line delcares the $stateProvider and $urlRouteProvider routing engine as function parameters where we can configure our routing for this application.
myApp.config(function ($stateProvider, $urlRouterProvider) {
Line-3: Ok, what does this line do is, if none of the routing engine matches the state which are delcared then it will take the default routing path to PageTab.html, that is what the state name is declared over there. Just to understand consider this is like default option in switch case statement.
$urlRouterProvider.when("", "/PageTab");
StateSection-1: This line is defining the first state which is going to get displayed in the main.html page as the first route when the page is getting loaded.
$stateProvider
.state("PageTab", {
url: "/PageTab",
templateUrl: "PageTab.html"
})
This is like a child page of the master page, when the application loads the main.html page.
StateSection-2: Now, This line is defining page, but wait, there is difference we have prefixed the above state name and separated that with (dot) ".". This is the key here what it tells to the routing engine is the page/route which we are declaring here is the sub page / nested page / nested state.
.state("PageTab.Page1", {
url:"/Page1",
templateUrl: "Page-1.html"
})
This is going to get displayed inside the page "PageTab.html" so what does it mean is. Imagine that when we wanted to host any page in the master page we wanted a placeholder called "ui-view", since we are calling the PageTab.html now as a master, because it is going to hold other pages we need to declare the "ui-view" inside the PageTab.html also. Let us change that now.
PageTab.html
<div>
<div>
<span style="width:100px"><a href="">Page-1</a></span>
<span style="width:100px"><a href="">Page-2</a></span>
<span style="width:100px"><a href="">Page-3</a></span>
</div>
<div>
<div ui-view=""/>
</div>
</div>
Ok, the below line..
<div>
<div ui-view=""/>
</div>
Says that the PageTab.html is going to host child page.
Clear now. Ok, but how. Who will tell what page needs to be displayed. This is what we have configured in the routing engine, as shown below.
.state("PageTab.Page2", {
url:"/Page2",
templateUrl: "Page2.html"
})
Page2.html will be displayed inside the state called PageTab, which is nothing but the PageTab.html.
Ok, but still we are missing something here, the thing is when we click on the Page-1 or Page-2 or Page-3 respective to that we wanted to show the page in the placeholder right. ?
That piece is really missing, that link we have not established yet, imagine if it is href mean we can give the ID name which is going to point inside the page, if it is simple html local reference means, but we are going to show different page as per the requirement.
The key here is this. (ui-sref) We need to change the PageTab.html again, as given below.,
<div>
<div>
<span style="width:100px" ui-sref=".Page1"><a href="">Page-1</a></span>
<span style="width:100px" ui-sref=".Page2"><a href="">Page-2</a></span>
<span style="width:100px" ui-sref=".Page3"><a href="">Page-3</a></span>
</div>
<div>
<div ui-view=""/>
</div>
</div>
Note, that the highlighted item above is the only change, so what we are doing here is simply associating the states delcared in the App.js to respective text delcared as tab. When we declare it as with DOT notation it is assumed that the page is sub page/ nested page inside the ui-view, which is delcared in the routing configuration needs to be displayed.
Now, we will see the content of all the pages so far we discussed.
Main.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-ui-router.js"></script>
<script src="App.js"></script>
</head>
<body data-ng-app="myApp">
<h1>AngularJS Home Page (Ui-router Demonstration)</h1>
<div data-ui-view=""></div>
</body>
<html>
PageTab.html
<div>
<div>
<span style="width:100px" ui-sref=".Page1"><a href="">Page-1</a></span>
<span style="width:100px" ui-sref=".Page2"><a href="">Page-2</a></span>
<span style="width:100px" ui-sref=".Page3"><a href="">Page-3</a></span>
</div>
<div>
<div ui-view=""/>
</div>
</div>
Page1.html
<div>
<div>
<h1>Page 1 content goes here...</h1>
</div>
</div>
Page2.html
<div>
<div>
<h1>Page 1 content goes here...</h1>
</div>
</div>
Page2.html
<div>
<div>
<h1>Page 1 content goes here...</h1>
</div>
</div>
App.js
var myApp = angular.module("myApp", ['ui.router']);
myApp.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.when("", "/PageTab");
$stateProvider
.state("PageTab", {
url: "/PageTab",
templateUrl: "PageTab.html"
})
.state("PageTab.Page1", {
url:"/Page1",
templateUrl: "Page1.html"
})
.state("PageTab.Page2", {
url:"/Page2",
templateUrl: "Page2.html"
})
.state("PageTab.Page3", {
url:"/Page3",
templateUrl: "Page3.html"
});
});
All set, now let us run the application.
Ok, the out is like this i got. (Igore the borders which i showed in the image, if you want you can have it created with simple CSS)
Below is the output when i click on the like 'Page-1'
The below is the output when i just open the page.
Ok, as per the screen above, this is the home page we are getting when we run the application at the first time. But some requirement is to show the Page-1 to be shown by default when we load the page. Fine, lets do that also with miner change in the routing.
$urlRouterProvider.when("", "/PageTab/Page1");
we have just added the highlighted item, where it will load the page with the nested child page when the home page is loaded. Hence the output would be now.
Hope this helps you guys... we will see in detail about Nested Named Views in my next article.
Happy Learning.. .:)