ui-router
module is used for state based routing in a web application.
It contains different directive like ui-view
and ui-sref
. The ui-sref is a directive that binds the href link to a
application state.
What is Single Page Application?
By Single page application we mean, a webpage that changes the url and content from the web server without reloading itself. Basically, it interacts with the user by dynamically rewriting the current web page with new data from the web server. It retrieves all the html, css and javascript elements with single page load but present them as requested by the user. If certain html elements are not requested by the user, it does not show up at all. Hence it makes website fast and more interactive which gives user a feeling of browsing through a native web app. Since, SPA does not require page reload, transition from one page state to another becomes faster and this way user need not wait during page reload as in multi page websites which takes time in reloading or redirecting to another url.
In this blog we will build a single page application using angular js. For this we will make following files.
- index.html
- app.js
- partial-home.html
- products.html
- contact-us.html
- partial-about.html
- table-data.html
Want to see a demo?
Also read, Angular web-application with ng-click AngularJS directive to create Like/Dislike Button
Create a home page for the application
In the body section we have created an angular application using
ng-app="routerApp"
directive. In the navbar section we have used
four ui-serf
directives.
These directives will automatically generate & update the href attribute via the $state.href()
method.
Clicking the link will trigger a state transition. In the next div section we have created a ui-view
.
A ui-view is a viewport component provided by the ui-router, when any state is activated
the state’s view (component) is rendered into the appropriate uiview viewport. Basically it binds an application state into a viewport.
index.html
<!DOCTYPE html> <html> <head> <!-- CSS (load bootstrap) --> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"> <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> <style> .navbar { border-radius:0; } </style> <!-- JS (load angular, ui-router, and our custom js file) --> <script src="angular.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script> <script src="app.js"></script> </head> <!-- apply our angular app to our site --> <body ng-app="routerApp"> <!-- NAVIGATION --> <div class="navbar navbar-default" role="navigation"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Project Name</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li ui-sref-active="active"><a ui-sref="home">Home</a></li> <li ui-sref-active="active"><a ui-sref="about">About Us</a></li> <li ui-sref-active="active"><a ui-sref="products">Products</a></li> <li ui-sref-active="active"><a ui-sref="contact-us">Contact Us</a></li> </ul> </div><!--/.nav-collapse --> </div><!--/.container-fluid --> </div> <!-- MAIN CONTENT --> <!-- THIS IS WHERE WE WILL INJECT OUR CONTENT ============================== --> <div class="container"> <div ui-view></div> </div> <div class="text-center"> <p>A tutorial by <a href="https://www.djtechblog.com" target="_blank"><span class="text-danger">Dj Techblog</span></a></p> </div> </body> </html>

Define states for all the pages in the angular single page web application
We create a module using the
module
function of the angular object and save it in a variable RouterApp.
The created module is dependent on a external module ui.router
, which is third party built in module.Next, we use the Angular config() function to setup a different states for the web application. We also define what to do if any undefined url or state caught or entered by the user. This will be handled by the
otherwise()
method. It takes an angular application state as an argument and will transit into that state
that is entered as an argument.
The application state can be defined using three variables, a name for the state, url of the state and template url.
We can also define a angular controller for the state whichis not compulsory.
At last we create a controller and pass a $scope
object to it. Within the controller we create an array of objects named phones.
Each phones object has some property defined.
app.js
var routerApp = angular.module('routerApp', ['ui.router']); routerApp.config(function($stateProvider, $urlRouterProvider) { $urlRouterProvider.otherwise('/home'); $stateProvider // HOME STATES AND NESTED VIEWS .state('home', { url: '/home', templateUrl: 'partial-home.html' }) .state('about', { url: '/about', templateUrl: 'partial-about.html' }) .state('contact-us', { url: '/contact-us', templateUrl: 'contact-us.html' }) .state('products.g3', { url: '/motorola-g3', views: { '': { templateUrl: 'motorola-g3.html'}, 'columnThree@products':{ templateUrl: 'motorola-g3.html', controller: 'mobilesController' } } }) .state('products.g4', { url: '/motorola-g4', views: { '': { templateUrl: 'motorola-g4.html'}, 'columnThree@products':{ templateUrl: 'motorola-g4.html', controller: 'mobilesController' } } }) .state('products.e4', { url: '/motorola-e4', views: { '': { templateUrl: 'motorola-e4.html'}, 'columnThree@products':{ templateUrl: 'motorola-e4.html', controller: 'mobilesController' } } }) // PRODUCTS PAGE AND MULTIPLE NAMED VIEWS .state('products', { url: '/products', views: { '': { templateUrl: 'products.html' }, 'columnTwo@products': { template: 'Click on the model to view the mobile.' }, 'columnOne@products': { templateUrl: 'table-data.html', controller: 'mobilesController' } } }); }); routerApp.controller('mobilesController', function($scope) { //$scope.message = 'test'; $scope.phones = [ { "id": "motorola-g3-16", "imageUrl": "g3", "name": "Motorola G3", "price": "8000", "desc": "Mobile description goes here" }, { "id": "motorola-g4-32", "imageUrl": "g4", "name": "Motorola G4", "price": "11000", "desc": "Mobile description goes here" }, { "id": "motorola-e4-32", "imageUrl": "e4", "name": "Motorola E4", "price": "10000", "desc": "Mobile description goes here" } ]; });
home page in the angular single page application
The
ui-view
viewport within the home page is bound to the home state which is defined in the app.js.
partial-home.html
<div class="jumbotron text-center "> <h1>The Home Page</h1> <p>This page demonstrates <span class="text-danger">nested</span> views.</p> </div> <div ui-view></div>
products page in the angular single page web application
In the products page we have three view ports. All the viewports are bound to the products state in the application.
products.html
<div class="jumbotron text-center"> <h1>The Products Page</h1> <p>This page demonstrates <span class="text-danger">multiple</span> and <span class="text-danger">named</span> views.</p> </div> <div class="row"> <div class="col-sm-6"> <div ui-view="columnOne"></div> </div> <div class="col-sm-6"> <div ui-view="columnTwo"></div> </div> <div class="col-sm-6"> <div ui-view="columnThree"></div> </div> </div>
Contact-us page in the angular single page application
contact-us.html
<div class="jumbotron text-center"> <h1>The Contact us Page</h1> </div>
About-us page in the angular single page application
partial-about.html
<div class="jumbotron text-center"> <h1>The About Page</h1> </div>
ng-repeat for nested views in the angular application
table-data.html page demonstrates the diffrent mobile brands in the tabular form. We use
ng-repeat
angular js directive to represent data in a table. The first column in the table contains a ui-sref
, which
binds a application state to a url. In the second column price is retrieved using {{phone.price}}
and in the third column we retrieve mobile description
using the binding expression {{ phone.desc }}
table-data.html
<h2>Motorola Mobile Phones</h2> <table class="table table-hover table-striped table-bordered"> <thead> <tr> <td>Model</td> <td>Price</td> <td>Description</td> </tr> </thead> <tbody> <tr ng-repeat="phone in phones"> <td><a ui-sref=".{{ phone.imageUrl }}" alt="{{phone.id}}">{{ phone.name }}</a></td> <td>Rs. {{ phone.price }}</td> <td>{{ phone.desc }}</td> </tr> </tbody> </table>
<!-- motorola-g3.html--> <div> <h2>Motorola G3</h2> <img src="motorola-g3-16.jpg" style="width: 40%"> <br><br> {{ phones.desc }} </div> <!--motorola-g4.html--> <div ng-controller="mobilesController"> <h2>Motorola G4</h2> <img src="motorola-g4-32.jpg" style="width: 40%"> <br><br> {{ phones.desc }} </div> <!-- motorola-e4.html--> <div> <h2>Motorola E4</h2> <img src="motorola-e4-32.jpg" style="width: 40%"> <br><br> {{ phones.desc }} </div>
If you face any issue while implementing the code, you can mail me. Thanks for patient reading.
Published on Jan 8, 2021