Friday, November 20, 2015

AngularJS and SPAs




AngularJS is MVW or MV*  or MVVM framework to develop large scale enterprise applications. AngularJS is a buzz word for modern web developers and some business specifically hire AngularJS developers.

It has made the front-end web development easier than ever with loads of cool features.

What does MVW means?


MVW - Model View Whatever. "Whatever" can thought as "Controller" in MVC, but in AngularJS this does mean that,

Whatever = Watch and Digest Loop in AngularJS

Here are some good resources to learn more about Watch and Digest Loop:

Benefits of SPAs

We can move around the web site without reloading it, just like our old school standalone desktop apps. AngularJS uses the hash or the pound symbol (#) to build up SPAs.


Let's look how we can build Single Page Application using AngularJS


Project Directory





angularmain.js

 
var firstApp = angular.module('firstApp', ['ngRoute']);

//route configurations
firstApp.config(function ($routeProvider) {
    $routeProvider
        .when('/', {
            templateUrl: 'webpages/home.html',
            controller: 'homeController',
        })
        .when('/about', {
            templateUrl: 'webpages/about.html',
            controller: 'aboutController',
        });
});


// controllers
firstApp.controller('homeController', ['$scope', function ($scope) {

    $scope.name = 'From Home Controller';

}]);

firstApp.controller('aboutController', ['$scope', function ($scope) {

    $scope.name = 'From About Controller';


}]);

firstApp.controller('mainController', ['$scope', '$location', function ($scope, $location) {

    // sets the active style for the navbar elements
    $scope.isActive = function (viewLocation) {
        return viewLocation === $location.path();
    };

}]);

Angular module is a where angular is initialized. Route Configurations enables us to implement SPAs where we are specifying the url, templateUrl - physical location of the webpage for the url, and it's associated controller.

In our example, "/" refers to the home or the index page which is the url, 'webpages/home.html' the home.html is located inside of webpages folder and "homeController" is it's controller responsible for it.

The scope object is only visible to it's respective controller. Ex: $scope.name in homeController and aboutController are different.


template.html

 
<!DOCTYPE html>
<html lang="en" ng-app="firstApp">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>AngularJS and SPAs</title>

    <!-- Bootstrap -->
    <link href="css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>

<body>
    <nav class="navbar navbar-default">
        <div class="container-fluid">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app1" aria-expanded="false">
                    <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="#/">
                    <span>AngularJS and SPAs</span>
                </a>
            </div>
            <div class="collapse navbar-collapse" id="app1" ng-controller="mainController">
                <ul class="nav navbar-nav navbar-left">
                    <li ng-class="{ active: isActive('/')}"><a href="#/">Home</a></li>
                    <li ng-class="{ active: isActive('/about')}"><a href="#/about">About</a></li>
                </ul>
            </div>
        </div>
    </nav>

    <div class="container" ng-controller="homeController">
        <div class="row">
            <div ng-view></div>
        </div>
    </div>


    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="js/bootstrap.min.js"></script>

    <!-- AngularJS Scripts -->
    <script src="//code.angularjs.org/1.4.7/angular.min.js"></script>
    <script src="//code.angularjs.org/1.4.7/angular-route.min.js"></script>

    <!-- External JS -->
    <script src="js/angularmain.js"></script>

</body>
</html>
The index page serves as the template page for the application. There are three AngularJS "custom attributes" used here:

  • ng-app - Specifies the angular module
  • ng-controller - the controller for the index page and what page of the page will it                            control
  • ng-view - This takes the view from the angular route configurations

home.html

 
<div class="form-group">
  <label for="inputBox">Text from Controller </label>
  <input type="text" class="form-control" id="inputBox" ng-model="name">
</div>
 
Gets the ng-model from the "homeController", ng-model is an angular directive and it is two way binding element. The term two way binding means that when the HTML is changed it automatically changes the Javascript and vice-versa.


about.html

 
<div class="form-group">
    <label for="inputBox">Text from Controller </label>
    <input type="text" class="form-control" id="inputBox" ng-model="name">
</div>
 


Final Result


Home Page

About Page


Further References and Tutorials