AngularJS

AngularJS is JavaScript-based front-end web application framework mainly maintained by Google for developing single-page web applications.

Links

Get AngularJS

You can download if from their site https://angularjs.org/ or get the AngularJS Googles CDN link to acess it directly from your HTML files

Simple example

Simple birthday list

<!DOCTYPE html>
<html ng-app="myFirstApp">
<head>
    <title>My First App</title>
    <link rel="stylesheet" href="bootstrap.css">
    <link rel="stylesheet" href="bootstrap-theme.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
    <script>
        // for demo we put in some hard coded values here
        var myInitialModel= {
            people: [
                { FirstName:"Thomas", Name:"Tom", birthYear:1965},
                { FirstName:"John", Name:"Doe", birthYear:1960},
                { FirstName:"Jane", Name:"Doe", birthYear:1970},
                { FirstName:"Child", Name:"Baby", birthYear:2016},
            ]
        };

        // your angular app with dependency injection
        var myFirstApp=angular.module("myFirstApp", []);

        myFirstApp.filter("adultsOnly", function() {
            return function(people, scope) {
                var result=[];
                people.forEach(function(person) {
                    if(scope.calcAge(person.birthYear)>=18)
                        result.push(person);
                });
                return result;
            }
            //return $scope.calcAge(person.birthYear)>=18;
        });

        // controller with code to do something with the model
        myFirstApp.controller("MyFirstController", function($scope) {
            $scope.myModel=myInitialModel;

            $scope.calcAge = function (year) {
                return new Date().getFullYear()-year;
            };

            $scope.isEmpty=function() {
                return typeof($scope.myModel.people)=='undefined' || $scope.myModel.people.length==0;
            };

            $scope.averageAge=function() {
                if($scope.isEmpty())
                    return 0;

                var ln=$scope.myModel.people.length;
                var sm=0;
                $scope.myModel.people.forEach(function(p) {
                   sm=sm+$scope.calcAge(p.birthYear);
                });
                return sm/ln;
            };

            $scope.addUser = function(newName, newFirstName, newBirthYear) {
                if($scope.isEmpty()) {
                    $scope.myModel.people=[];
                }
                var tmp={ FirstName:newFirstName, Name:newName, birthYear:newBirthYear};
                $scope.myModel.people.push(tmp);
            };
        });

    </script>
</head>
<!-- The view is plain HTML, we need to attach the controller to an element so its code is available here in the view-->
<body ng-controller="MyFirstController">
<h1>People List</h1>

<!-- Standard HTML form, calls addUser method of the controller once you hit the button-->
<h2>Add new</h2>
<div>
    First Name: <input class="form-control" ng-model="newFirstName" />
    Name: <input class="form-control" ng-model="newName" />
    Birth Year: <input class="form-control" ng-model="newBirthYear" />
    <button class="btn" ng-click="addUser(newName, newFirstName, newBirthYear)">Add</button>
</div>

<!-- Hide HTML elments based on controller logic-->
<div ng-hide="isEmpty()">
    <h2>List of all people</h2>
    <!-- This shows how to call a function in the controller and print its result-->
    Average age of people in list: {{ averageAge() }}
    <!-- Stadard HTML table, the rows are create automatically by ng-repeat reading the model-->
    <table class="table">
        <tr>
            <th>Name</th><th>First Name</th><th>Age</th>
        </tr>

        <tr ng-repeat="onePerson in myModel.people | adultsOnly:this">
            <td>{{onePerson.Name}}</td>
            <td>{{onePerson.FirstName}}</td>
            <td>{{calcAge(onePerson.birthYear)}}</td>
        </tr>
    </table>
</div>

</body>
</html>

Now lets see how to split all that into different files and go into some details

Controller

You have a block of HTML. Inside that block you want Angular to change some of the HTML. The code that will be responsible for that is the controller.

<div ng-controller="MyFirstController">
  Here happens the magic
</div>

The controller code can (and should) be in its own file. Syntax of the very first row is slightly different compared to the all in one file variant. We first need to get the module by name (leave out the dependencies parameter). This .js file can be include like any other js file from the HTML with the script element.

angular.module("myFirstApp").controller("MyFirstController", function($scope) {
...

The filter code also should go into its own file.

angular.module("myFirstApp").filter("adultsOnly", function() {
            return function(people, scope) {
                // ...
            }
};

The filters can also go into another module than "myFirstApp" and can be used my multiple modules.

angular.module("myFilters", []).filter("adultsOnly", function() {
            return function(people, scope) {
                // ...
            }
};

In this case we also need to declare a dependency to the new module

angular.module("myFirstApp", ["myFilters"]);

The view (the HTML) should also be separated files. The can be included with

<ng-include src="'views/foo.html'" />

Filter

An AngularJS filter takes some values and returns other values. It may format values, sort values, add extra values, or even filter out values (the only case where an AngularJS filter actually really filters). There are predefined filters and you can write your own ones.

Turn a number into a formated currency

Price: {{myModel.price | currency }}
Price: {{myModel.price | currency:'€' }}

(Real filter) and sort

<tr ng-repeat="item in myModel.people | filter:{selected: true} | orderBy:'name'">

Custom filter

myFirstApp.filter("myFilter", function() {
            return function(items) {
                // return something based on items
            }

Here are more filters [[ https://docs.angularjs.org/api/ng/filter | More AngularJs filter ]

You can also use those filters in your own ones if you have a dependency on $filter

myFirstApp.filter("myFilter", function($filter) {
            return function(items) {
                $filter("limitTo")(...);
            }

Filters can be chained together, separated with | and are executed from left to right

Visibility

The CSS class of an element can be the result of a function call

<div class="foo()">

And ng-show / ng-hide can even hide elements based on the result of a function call

<div ng-show="bar()">
<div ng-hide="bar()">
 

Click events

Do something when element is clicked

<a ng-click="functionInController()" ...

constant

You can add constants to the module for later use

angular
    .module('myFirstApp', [])
    .constant("myURL", { "url": "http://localhost", "port": "80" })
    .controller('MyFirstController', function (myConfig) {
        // ...
    });

Services

A Singelton that holds functions and data. Put that into a file called foo.js

angular.module("myServices", [])
 .factory("myFirstService", function() {
  var data1=0;
  var data2=0;
  return {
    myFunction: function(bar) {
      ...
    }
  };
});

If you want to use that service you have to include the file like this <script src="foo.js"></script>

And in the module where you want to use the service, name the module where you did put your service (not the service itself) it as dependency

angular.module("someOtherModule", ["myServices"])

and you can pass in the Service myFirstService as an parameter