Concisely how to get started with AngularJS


2013-07-26 · 7 min read

Today we'll dive into AngularJS realm. As usual, I'll try to explain principal concepts of that framework along with examples in the most concise way I can. Hopefully, it will help you start coding in no time.

AngularJS was created by Miško Hevery and it's maintained by Google. Its current stable version is 1.0.7. AngularJS make use of declarative programming for building UI. It extends HTML with custom elements, called directives.

For the code examples I assume that angular.js script is included in the <head> and that the <html> is decorated with ng-app directive - this boots AngularJS.

<html ng-app>
    <head>
        <script type='text/javascript' src='http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.min.js'></script>
    </head>
    <body>
        ... Paste snippets in here ...
    </body>
</html>

In the following code snippets, I'll be showing only the content from inside of the <body>.

We have 8 concepts to cover: Model-View-ViewModel, Dependency Injection, Data Binding, Controller, Template, Service, Filter and Directive.

Model-View-ViewModel

Model-View-ViewModel (MVVM) is an architectural pattern based on MVC and targeted at UI development. MVVM helps separate business logic (model) from the UI (view) using the view-model which adapts the data from the model so the view can easily manage them. Model is also single source of truth for the view. AngularJS uses plain JavaScript objects for the model, while $scope object (also a JavaScript object with additional methods to manage its state) represents ViewModel. $scope allows to define both the data and methods that will be available for the view.

Dependency Injection

Dependency Injection is a software pattern which means: If an object needs another object (a dependency), this dependency is being passed to it instead of being constructed (e.g. initialised) by that object. Imagine it in the following way: you define what objects you need and they are immediately ready to work for you. It makes the application easier to develop

Data Binding

AngularJS provides Two-Way Data Binding. It is two-way because the data can go from the model to the DOM and from the DOM to the model. In other words:

  • if somethings changes in the model e.g. new blog posts being pushed by the server, it will be automatically reflected in the DOM i.e. on the view;
  • if you interact with the view (e.g. mouse click) to delete a blog post, the model will be automatically notified about that change.

Such data binding is very practical as in web applications, there is often a lot of code that concerns the DOM manipulation.

Take a look at this basic 2-way data binding (snippet).

<input type="text" ng-model="message" placeholder='Type your message here...' />
<h1>{{message}}</h1>

When you start writing inside the input field, the data is sent to the model and then back to the view and displayed below the input field . In this example the model is declared through the view, right inside the HTML using ng-model directive, and named message. $scope, in this example, is not used directly.

Controller

Controllers set initial state for the model, using $scope object, and optionally augment $scope with methods. The model is then available in the part of the DOM associated with that scope (data binding). A controller can be a simple JavaScript function. Controllers do not store state nor interact with remote services.

In the example below ng-controller associates MyCtrl controller with a particular div (a node in the DOM), which becomes this controller's scope (snippet).

var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
  $scope.message = 'from MainCtrl';
});
<div ng-controller="MainCtrl">
  <h1>Output: {{message}}</h1>
</div>

As before, message is saved via $scope in the model and then displayed in the view using AngularJS interpolation i.e. {{ }}.

Templates

Templates in AngularJS are HTML files with an extended vocabulary. This vocabulary consists of directives which show how the model should be represented on the view. AngularJS (compiler) manipulates on the DOM, and not on strings (in contrast to other JavaScript frameworks), e.g. while looking for these directives.

Service

Services are used to manipulate data and shared it between controllers. In other words, they provide a centralised access to the data. They are singletons, which means there is always only one instance of a given service.

In the example below, a service is shared between two controllers. This way each controller can access and manipulate the data that was entered in the input managed by the other controller (its scope).

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

app.service('MessageService', function () {
    this.payload = { message: 'Hello from a Service' };
});

app.controller('FirstCtrl', function ($scope, MessageService) {
    $scope.payload = MessageService.payload;
});

app.controller('SecondCtrl', function ($scope, MessageService) {
    $scope.payload = MessageService.payload;
});
<body ng-app="app">
    <div ng-controller="FirstCtrl">
        <input type="text" ng-model="payload.message"/>
    </div>

    <div ng-controller="SecondCtrl">
        <input type="text" ng-model="payload.message"/>
    </div>
</body>

Filter

Filters are helpers that adjust the data presentation on the view. For example, a builtin number filter helps to format numbers with decimal places (snippet)

<input ng-model="value" type="text" placeholder='Try to enter a number with 3 or more decimal places...'/>
<h1>{{value | number:2}}</h1>

You can also create your own filter. Below a filter that reverses the entered text (snippet).

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

app.controller('MainCtrl', function($scope) {
    $scope.message = 'This is simple message';
});

app.filter('reverse', function() {
    return function(input, param) {
        return input.split("").reverse().join("");
    }
});
<div  ng-controller="MainCtrl">
    <h1>Orginal: {{message}}</h1>
    <h1>w/ filter: {{message | reverse }}</h1>
</div>

Filters can be also used when iterating over elements with ng-repeat directive (this directive creates a separate scope for each element of the list).

A builtin orderBy filter orders elements by given field (snippet).

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

app.controller('MainCtrl', function($scope) {
    $scope.books = [
        {
            title: 'Introduction to Algorithms',
            author: 'Thomas H. Cormen'
        },
        {
            title: 'The C Programming Language',
            author: 'Brian W. Kernighan'
        },
        {
            title: 'Effective Java',
            author: 'Joshua Bloch'
        },
    ];
});
<ul ng-controller="MainCtrl">
   <li ng-repeat="book in books | orderBy:'book.title'">
       <p>{{book.title}} / <em>{{book.author}}</em></p>
   </li>
</ul>

Another interesting iteration filter is search. Check how it works in this snippet.

Directive

Directives allow to extend HTML, they can be used to create custom HTML tags, or to decorate existing ones with new behaviour.

Let's create a directive that adds a copyright information using a new <copyright> tag (snippet).

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

app.controller('MainCtrl', function($scope) {
    $scope.message = "Hi, I'm an AngularJS app";
});

app.directive('copyright', function() {
  return {
    restrict: "E",
    replace: true,
    template: "<p>Copyright 2013</p>"
  }
});
<body ng-app="app" ng-controller="MainCtrl">
  <h3>{{ message }}</h3>
  <copyright></copyright>
</body>

Directives have several types. restrict: "E" means we should use a HTML tag to reference it, i.e. <copyright>; other possibilities are: restrict: "A" for attribute i.e. <div copyright>, restrict: "C" for class i.e. <div class="copyright">. template specify the HTML content that should be displayed when it's executed.

Summary

[14]: