Angular Tutorial – Part 3: Understanding and using Directives

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 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 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 fairly an advance 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 the angular and find ourself in much position to dive into details of creating custom directives. So lets 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 following.

angualr3_1

What this above code will do is that, it will look at the ng-app directive and initialized the angular application. It will then look for the angular module myAngularApplicationand 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-controllerdirective 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 ngControllerdirective.

angualr3_2

ngController directive attaches the view with the controller defined in the directive. So in the above code, the booksControllerwill 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 the in the above code, if its defined in the booksController, the value of the messageproperty will be shown here. Lets look at the controller code to see how the message property is defined on $scope in our controller.

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.

angualr3_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 details 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 lets say we want to initialize the value of $scope.message2using ng-init rather than in our controller, we can do something like following.

angualr3_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.

angualr3_5

However we should never use ng-init in this manner because this will lead to the spaghetti code again. We will have tough time in 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 ngBinddirective 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.

angualr3_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 bgBindHtmlavailable 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. Lets see how we can use ngModel on our view.

angualr3_7

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

angualr3_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. Lets see how this can be used to iterate over a list of books defined our $scope.books.

angualr3_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 provide a directive specifically for this purpose. ngOptions let us populate the options of dropdown list easily. Lets say we have a list of countries specified in an array on the $scope.countriesvariable.

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

angualr3_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.

angualr3_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 let 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.

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

Currently this function is populating the $scope.bookswith some hard coded values. Now lets look at the ng-click directive in the view.

angualr3_12

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

angualr3_13

Note: Similar to ngClick there are few other directives available that makes 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 evaluates the expression provided and then selectively show or hide the UI elements. So lets 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.

angualr3_14

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

angualr3_15

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

angualr3_16

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

angualr3_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 ngIfdirective instead.

ng-style and ng-class

If we want to apply a CSS style to any of the DOM element 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 > 0evaluates 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 beginner’s perspective and I hope it has been informative.

Download the sample code for this article here: SampleApp3