Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Angular Tutorial - Part 3: Understanding and Using Directives

4.84/5 (42 votes)
5 Jul 2015CPOL12 min read 40.4K   956  
Understanding the basic concept of directives in Angular - how directives are used in Angular and using some built in directives in Angular.

Introduction

In this article, we will try to understand the basic concept of directives in Angular. We will look at how directives are used in Angular and try to use some built in directives in Angular.

Link to complete series:

  1. Angular Tutorial - Part 1: Introduction to Angular.js
  2. Angular Tutorial - Part 2: Understanding Modules and Controllers
  3. Angular Tutorial - Part 3: Understanding and Using Directives
  4. Angular Tutorial - Part 4: Understanding and Implementing Filters
  5. Angular Tutorial - Part 5: Understanding and Implementing Services
  6. Angular Tutorial - Part 6: Building and Validating Data Entry Forms
  7. Angular Tutorial - Part 7: Understanding Single Page Applications and Angular Routing

Background

Traditionally, web only consisted of static HTML pages linked with each other. Rise of server side technologies enabled us to create the HTML dynamically on the server side and push it back to the client. But in both cases, the generated HTML contains the elements and attributes that are defined in the HTML specifications. With directives, Angular has taken things to the next level.

What Angular directives provide us is that they let us write our own HTML elements and attributes. This would mean that now we have a possibility of extending the HTML vocabulary and define our own logic and behaviour in the form of HTML-like elements and attributes. We can create directives to custom elements, attributes and even HTML comments.

Using the Code

The topic of directives in Angular can be broken into two parts. First, we can talk about the built in directives provided by Angular and how we can use them in our application. Second, how can we create a custom directive ourselves to create a reusable piece of functionality in the form of a directive.

Built in Directives in Angular

In this article, we will be talking about the most commonly used built in Angular directives. Creating custom directives is a fairly advanced topic and we will talk about that in the 9th article of the series as by then, we must have looked at other aspects of Angular and find ourselves in much better position to dive into details of creating custom directives. So let's get started with the built in directives in Angular one by one.

ng-app

In the previous articles of this series, I have mentioned that we need to put ng-app in the HTML element where we want to use the Angular app. What is this ng-app? ng-app is a built in Angular directive. What ng-app directive does is that it will define the root of an Angular application.

The element on which it is defined, all the elements contained within that element are then a part of the Angular app. Usually, we put it on the HTML element itself so that the complete HTML page becomes a part of the Angular application. It is possible to just write ng-app without any parameter and this will bootstrap the Angular application in automatic mode. However, it is not a good idea to do so as it is little tricky to manage dependencies and specify the starting point of the application if we do this.

Instead, what we should do is that we should pass the Angular module name that should be used for this page. So if we have a module defined as myAngularApplication. Then the ng-app directive should look like the following:

Image 1

What this above code will do is that, it will look at the ng-app directive and initialize the Angular application. It will then look for the Angular module myAngularApplication and treat it as the starting point of the application. Having the ng-app directive manually bootstrap the application is beneficial as it gives us a chance to specify the module that can be treated as the entry point and all the components (controllers, services, filters, etc.) that depend on the specified modules can be used easily.

ng-controller

We have also looked at the ng-controller directive in the previous article. Whenever we want any view to be associated with any controller, we can attach the controller to the view using the ngController directive.

Image 2

ngController directive attaches the view with the controller defined in the directive. So in the above code, the booksController will get associated with the body of this HTML document. The HTML element that contains the ngController directive can then access all the properties defined in the controller. The {{message}} that we are accessing in the above code, if it's defined in the booksController, the value of the message property will be shown here. Let's look at the controller code to see how the message property is defined on $scope in our controller.

JavaScript
(function () {

    var booksController = function ($scope) {
        $scope.message = "Hello from booksController";

        this.greeting = "This is a greeting message using controller as syntax";

        $scope.books = [];

        $scope.fetchBooks = function () {
            $scope.books = [
                { ID: 1, BookName: "Test Books 1", AuthorName: "Test Author 1", ISBN: "TEST1" },
                { ID: 2, BookName: "Test Books 2", AuthorName: "Test Author 2", ISBN: "TEST2" },
                { ID: 3, BookName: "Test Books 3", AuthorName: "Test Author 3", ISBN: "TEST3" },
                { ID: 4, BookName: "Test Books 4", AuthorName: "Test Author 4", ISBN: "TEST4" },
                { ID: 5, BookName: "Test Books 5", AuthorName: "Test Author 5", ISBN: "TEST5" }
            ];
        }
    }

    angular.module('myAngularApplication').controller('booksController', ["$scope", booksController]);
}());

We have talked about the controller as syntax briefly in the previous article. We can use the ngController directive to also let the view use the controller code using the controller as syntax. What "controller as" syntax does is that it will let the view access all the properties defined on the controller object.

Image 3

So what the above code will do is that it will show use the greeting property of the controller and show its value in the view. Using this approach would mean that we don't have to push the values in the $scope but rather we can have controller have the properties and using controller as syntax, the view should be able to use it.

Note: There are scenarios where we don't have to explicitly use the ngController directive explicitly in a view to bind it with the controller. One example is while using routing, we can attach the controller with a view in the route definition. But we will look at that in detail in later articles that how Single Page Applications where we use $route or uiRouter don't need the ngController directive in the view. But for non-SPAs, ngController is the way to attach the view with the controller.

ng-init

ngInit directive is used to initialize the data in the $scope. What ng-init does is that it will look at the expression and initialize the value of the $scope variable. So let's say we want to initialize the value of $scope.message2 using ng-init rather than in our controller, we can do something like the following:

Image 4

Now if we run he application, we can see that the $scope.message2 was initialized using ng-init and its value appears on the screen.

Image 5

However, we should never use ng-init in this manner because this will lead to the spaghetti code again. We will have a tough time identifying whether the value of a particular scope variable is initialized in the controller or in the view using ng-init. The recommended use of ng-init is only to alias the code that is needed in the view only. One example could be that we might have a long filter expression in our view and we want to use this filter expression in multiple places. In this case, we can use ng-init to alias this expression and use the alias in all the needed places in the view.

ng-bind

The ngBind directive can be used to display the properties on $scope on the view. When we use the expression {{ ... }}, it is also equivalent to ng-bind. So if we want to use the ngBind directive to display the message, we need to do the following in the view.

Image 6

If we run the page, we can still see the message being displayed like before but this time we are explicitly using the ngBind directive instead of the {{ .. }} syntax. The important thing to note while using ngBind is that it is a one way binding, i.e., if we use ng-Bind to bind a scope property to an input field, changing the input field will not change the value of the scope property. If we need this behaviour, we need to use ngModel instead.

Note: If we want to bind the raw HTML text to the view, there is a directive called bgBindHtml available that can be used.

ng-model

ngModel is also very similar to the ngBind in the sense that it attaches the scope properties with view. But the most important difference and perhaps the benefit is that, ngModel gives us a two way binding. So if we attach an input field with a scope property using ngModel, changing the input field value will also change the value of the scope property. Let's see how we can use ngModel on our view.

Image 7

Now if we change the value of the textbox, we can see the value of the scope property also being changed.

Image 8

ng-repeat

There are scenarios where we might want to iterate over a collection and display each individual element on the view. ngRepeat is useful for such scenarios. ngRepeat can iterate over all the items of the collection and display each item in the specified view format. Let's see how this can be used to iterate over a list of books defined our $scope.books.

Image 9

The above code will use ng-repeat directive to iterate over the list of books ad display each book in a row.

ng-options

The ngRepeat directive that we saw above can be used to populate the values in dropdown lists. But Angular provides a directive specifically for this purpose. ngOptions lets us populate the options of dropdown list easily. Let's say we have a list of countries specified in an array on the $scope.countries variable.

JavaScript
$scope.countries = [
    "India",
    "Denmark",
    "USA",
    "Singapore",
    "Germany"
];

Now if we want to display this list as options of dropdown list, we can do this in the following manner.

Image 10

What the above code is doing is that it is binding the select list with the countries property using the ng-model directive. Then, we are using ng-options directive to fill the options of the select list from the countries collection. If we run this, we can see the values being shown as options of the dropdown list.

Image 11

ng-click

When using Angular, we don't have to explicitly attach the click events with the DOM elements to handle the click behaviour. Angular provides a directive called ng-click which lets us easily handle the click events on the DOM elements. What we can do is that we can use ng-click directive to attach a controller function with the click event and whenever a click occurs, the controller function will get invoked.

Let's first define a simple function on the scope (in the controller) that will be invoked when a button is clicked.

JavaScript
$scope.fetchBooks = function () {
    $scope.books = [
        { ID: 1, BookName: "Test Books 1", AuthorName: "Test Author 1", ISBN: "TEST1" },
        { ID: 2, BookName: "Test Books 2", AuthorName: "Test Author 2", ISBN: "TEST2" },
        { ID: 3, BookName: "Test Books 3", AuthorName: "Test Author 3", ISBN: "TEST3" },
        { ID: 4, BookName: "Test Books 4", AuthorName: "Test Author 4", ISBN: "TEST4" },
        { ID: 5, BookName: "Test Books 5", AuthorName: "Test Author 5", ISBN: "TEST5" }
    ];
}

Currently, this function is populating the $scope.books with some hard coded values. Now let's look at the ng-click directive in the view.

Image 12

Now when we click on the button, the fetchBooks function will get called and the $scope.books will get populated with some predefined values which in turn will be visible on screen.

Image 13

Note: Similar to ngClick, there are few other directives available that make the DOM event handling very easy. Few of these directives are: ngDblClick, ngMousedown, ngMouseenter, ngMouseleave, ngMousemove, ngMouseover, ngMouseup, ngKeyPress, ngKeyDown, ngKeyUp, ngBlur, ngFocus.

ng-show & ng-hide

There are two directives, ngShow and ngHide which evaluate the expression provided and then selectively show or hide the UI elements. So let's say in our current application, we want to display a message "No books available" till the user clicks on the button. We can do that by using ng-hide directive.

Image 14

What the above code is doing is that it is hiding the message when the count of number of books is more than 0. So when we start the app, the page will look like:

Image 15

Now let's say once the button is clicked, the count will be more than 0, we now need to show the books details in a table. Let's see how we can do this using ng-show directive.

Image 16

Now when we click on the button, the table will show up with the list of books.

Image 17

Note: It is important to note that the ng-show and ng-hide only plays with the visibility of the DOM elements. The element will still be rendered on the page just hidden. If we want to prevent the rendering of the element itself, then we should use ngIf directive instead.

ng-style and ng-class

If we want to apply a CSS style to any of the DOM elements, then we can use ng-style directive as ng-style="{color: mycolor}" where my color is a variable defined on scope. ng-style uses the actual value to apply the CSS style and the value comes from a property defined on scope. There is a similar directive called ng-class which can be used to apply a CSS class on a DOM element. How ng-class works is like it evaluates a boolean expression and applies the class if the expression is true. So if we do something like "ng-class={myclass: books.length > 0}", if books.length > 0 evaluates to true, myclass will be applied on the DOM element. The actual styles for this class can then be defined in the CSS file.

Point of Interest

In this article, we tried to look at what Angular directives are. We also looked at few of the built in directives in Angular. There are a lot of built in directives available in Angular that we have not talked about here. Also, a lot of community created directives are also available to use. So perhaps before trying to solve any problem the old school way, it is always to good idea to check if there is any built in or third party directive available for use.

The idea of this article was to get the reader acquainted with the way Angular directives work by showing the usage of some common built in directives. In later part of this series, we will also look at how to create a custom directive ourselves. This article has been written from a beginner's perspective and I hope it has been informative.

History

  • 6th July, 2015: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)