AngularJs Basics

You can download the AngularJs to use via CDN. I am using doing my examples in

  • Visual Studio Code (VSC)
  • Live Server plugin for the VSC

Angular application based on the model-view-controller pattern. The view is based on the DOM. The controllers are JavaScript classes and the model data is stored in object properties1.

  • The model (line# 10) represent the current state of the application.
  • view (line# 12) for display the data
  • controllers manage the relationships of model and views.

Here the simplest two way binding where UI is mapped to JavaScript properties.

<!doctype html>
<html ng-app>

<head>
    <title>My AngularJS App</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
</head>

<body>
    Value : <input type="text" ng-model="val" placeholder="cost" />
    <p>
        This is your value: {{val}}
    </p>
</body>

</html>

The binding agent is $scope(not only that there $location and so on. As shown in the line# 12 double-curly interpolaton insert val content to the template. If you run the above code, your output will be like the following.

In the above screenshot, you can enter the value for the input box and which will display in the text.

Controller

So far what we work with is view in the model-view-controller pattern. The controller is a manager/coordinator, for example, if you want initial value for above input.

<head>
  ...
  </script>
    <script>
        function ValCtrl($scope) {
            $scope.val = 1000.1;
        }
    </script>
</head>
<body ng-controller="ValCtrl">
...

As shown in the above, the controller is ValCtr. But in addition to that, you have to add the controller to the body element before your test. Please see for Nested Controllers.

Scope

Angular doesn't share the data. If you duplicate the code inside the body to have multiple input elements, one element change will affect response to one text. To explain this, say we need a multiplier as well.

function ValCtrl($scope) {
     $scope.val = 1000.1;
     $scope.multiply = $scope.val * 2;
}

And add the text to the body section.

<p>
    This is the result of multiplication: {{multiply}}
</p>

In the page load, you will find values are initialised as expected, but when you change the value, nothing will be changed. The solution is the watch function.

function ValCtrl($scope) {
    $scope.val = 1000.1;
    $scope.$watch('val', function() {
        $scope.multiply = $scope.val * 2;
    }

Styling

Here the way to styling the total.

//display total
$scope.$watch('total', function() {
     $scope.total_display = $scope.total ? 'block' : 'none';
});

Add the following styling to the paragraph as follows

<p style="display: {{total_display}}">
    This is the result of multiplication: {{multiply}}
</p>

As shown above, based on the total, decide whether to display the bloc (true) otherwise none (false).

UI Components

For example

<!doctype html>
<html ng-app>

<head>
    <title>Select example</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js"></script>
    <script>
        function ValCtrl($scope) {


            $scope.cities = [{
                id: 1,
                country: 'Australia',
                capital: {
                    name: 'Sydney'
                }
            }, {
                id: 2,
                country: 'Sri Lanka',
                capital: {
                    name: 'Colombo'
                }
            }];
            $scope.my_city = $scope.cities[1];

        }
    </script>
</head>

<body>
    <div ng-controller="ValCtrl">
        City: <select ng-model="my_city" ng-options="item as item.country for item in cities track by item.id"></select>
        <p>
            Capital of the {{my_city.country}} is {{my_city.capital.name}}
        </p>
    </div>

</body>

</html>

As shown in the above, the select UI component select the c

Data Structure

We will start with the simplest data structure array::

<!doctype html>
<html ng-app>

<head>
    <title>My AngularJS App</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js"></script>
    <script>
        function Ctrl($scope) {
            $scope.students = ["Ojitha", "Mark", "Nimal"];
        };
    </script>
</head>

<body ng-controller="Ctrl">
    {{students}}
</body>

</html>

Above code directlly show the out put such as ["Ojitha","Mark","Nimal"]. You can further format

<body ng-controller="Ctrl">
    <div ng-repeat="student in students">
        {{student}}
    </div>
</body>

Nested Controllers

If you have complex sections of your UI to maintain, you can keep your code simple by creating nested controllers that can share Angular Model and functions through an inheritance tree. For example, in the following code nested contoller is StudentCtrl without the scope show and hide methods will not be visible.

<!doctype html>
<html ng-app>

<head>
    <title>use of nestead controller</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js"></script>
    <script>
        function Ctrl($scope) {
            $scope.students = [{
                name: "Ojitha",
                subjects: ["Maths", "Physics"]
            }, {
                name: "Mark",
                subjects: ["Englis", "Art"]
            }, {
                name: "Nimal",
                subjects: ["Religon", "History"]
            }];
        };

        function StudentCtrl($scope) {
            $scope.show = function() {
                $scope.student.show_subject = true;
            };

            $scope.hide = function() {
                $scope.student.show_subject = false;
            }
        };
    </script>
</head>

<body ng-controller="Ctrl">
    <div ng-repeat="student in students" ng-controller="StudentCtrl">
        {{student.name}} (
        <a href="#" ng-click="show()" ng-hide="student.show_subject">show</a>
        <a href="#" ng-click="hide()" ng-show="student.show_subject">Hide</a> )

        <div style="margin-left: 50px;" ng-show="student.show_subject">
            <div ng-repeat="subject in student.subjects">
                {{subject}}
            </div>
        </div>
    </div>
</body>

</html>

In the above code nesting is defined in the body. The parent controller Ctrl is assign at line# 33 and the nested controller StudentCtrl assigned at line# 34. The actual nesting happens in scopes. The $scope passed to a nested controller prototypically inherits from its parent controller’s $scope.

Modules

Module provide namespace for related parts.

<!doctype html>
<html ng-app="myApp">

<head>
    <title>module example</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.9/angular.min.js"></script>
    <script>
        var mod = angular.module('myApp', []);

        mod.controller('Ctrl',
            function($scope) {
                var someText = {};
                someText.message = 'Hello World';
                $scope.someText = someText;
            });
    </script>
</head>

<body ng-controller="Ctrl">
    <p>{{someText.message}}</p>
</body>

</html>

In the above code ng-app has defined as "myApp". This will keep the things out of the global namespace. Here ng-app defined the template boundaries.

Data Binding to Template

You can understand the following sequence diagram now becuase you know what is happening practically.

sequenceDiagram
    participant u as User
    participant b as Browser 
    participant s as Server
    participant a as Angular
    
    u->>+ b: (1) request a first page
  b->>+ s:  http request
  s-->>+b: (2) html
  b->>+a: (3) look "ng-app"
  loop until load all 
      a->>+b: (4) look directives and bindings
  end                           

Step 1 to 3 is common for all the applications.

Reference


  1. AngularJS by Shyam Seshadri and Brad Green, 2013. 

Comments

Popular posts from this blog

How To: GitHub projects in Spring Tool Suite

Spring 3 Part 7: Spring with Databases

Parse the namespace based XML using Python