AngularTutorials

Learn Angular Step by Step – Session 6 : Angular directives

In angular there are 3 kind of directives which can be called as components, structural directives and attribute directives. Lets discuss more about them in this session.

              1- Components

At this moment you know about the components. Those are the most common type from this three.

               2- Structural directives.

These type of directives change the “DOM” layouts by adding or removing elements. Simply we can say structural directives are changing the elements in the view. *ngIf and *ngFor are two common types of structural directives.  *ngIf directive will add elements when a condition becomes true and *ngFor can be used to loop through a array or list and show some elements.

First let’s take *ngIf.  

Let’s say we want to show error message when there is a error or we want to show success message when some action become success. These kind of scenarios need a conditional statements to handle the user view.

To demonstrate this scenario we can add a temporary button to the previous application we built. Let’s say we want to show a name of a book when I press the load button. 

To handle that I will add a button and book details to app.components.ts.

<div class="container">
    <button class="btn btn-primary"> Load</button>
    <hr>
    <div class="card container">
        <h3> Famous Five</h3>
        <p>Enid Blyton</p>
    </div>
</div>

Now it will look like below.

Now I will go to app.component.ts file and create a new boolean type variable to keep the load status and create a method to change the load status.

  isLoaded : boolean = false;

  Load() {
    this.isLoaded = true;
  }

Then I will go again to app.component.ts file and change add click event to button and add *ngIf to book details card.

<div class="container">
    <button class="btn btn-primary" (click)="Load()"> Load</button>
    <hr>
    <div class="card container" *ngIf="isLoaded">
        <h3> Famous Five</h3>
        <p>Enid Blyton</p>
    </div>
</div>

So now if you go to the website we built and reload it, you will not see the book details card. But if you press load button suddenly it will appears. This is one thing we can do with *ngIf. Further please note that you can use AND, OR, NOT operators as usual in other programming languages. NOT will denoted by ! , AND will denoted by &&, OR will denoted by ||.

next we will go through *ngFor

*ngFor is simply used to loop though an array or list and display some content. To demonstrate this we will change our application to show a list of books with it’s name and author. since we do not need the load function above which we have added to demo the *ngIf I will delete the *ngIf part in the html and isLoaded variable and Load() method in the ts file.

Then I will edit app.component.ts with adding the following array.

bookList : { name: string, author: string }[] = [
    {
      "name": "Famous Five",
      "author": "Enid Blyton"
    },
    {
      "name": "Harry Potter",
      "author": "J. K. Rowling"
    },
    {
      "name": "Hamlet",
      "author": "William Shakespeare"
    },
    {
      "name": "Sherlock Holmes",
      "author": "Arthur Conan Doyle"
    },
  ]

If we closer look up the above array you can see bookList is the name of the array. Then we have put colon and added the type definition for the array. In the future we will create a interface for this, For the moment lets keep it as it is and add the values into it.

Then I will edit the app.component.html file to show these values. So I will add *ngFor statement instead of *ngIf (since we have implemented it only to demo the above directive) , remove load button and add some classes to make it more attractive.

<div class="container">
        <h1> Book List</h1>
        <hr>
    <div class="card container lib-book-card" *ngFor="let Book of bookList">
        <h3> {{Book.name}}</h3>
        <p>{{Book.author}}</p>
    </div>
</div>

Here you can see inside *ngFor I have declared the variable Book and this will loop through the bookList and assign each value to “Book”. So we can access name and the author by Book.name and Book.author.

To make it more nicer I have added the following styles to app.component.scss.

.lib-book-card {
    padding: 10px 20px;
    margin: 10px;
    background: #fafafa
}
.lib-book-card:hover {
    background: #fafffa;
    cursor: pointer;
}

Now our app will look like follows.

Now we have learned how to use *ngIf and *ngFor. Those are only two of structural directives and you will meet more of them while you are learning angular. So what we can monitor here is those directives are adding some elements to the view or DOM. As we above discussed that is the reason for calling them as structural directives.

3 – Attribute directives.

Attribute directives change the behavior of component, element or another directive. For example let’s say we want to change the background color of a div once a condition is true then we have to use attribute directives. They will not change the structure of the DOM but they will change the appearance. ngStyle and ngClass are two common attribute directives which can use to add some css properties to an element.

First we will discuss about ngStyle

ngStyle can be used to add inline styles depending on a condition. To demonstrate this lets go back to our application. Let’s say our friends will borrow books from our book list. So some books will be availble at a moment while some have been borrowed by friends. So I will update our array by adding a new field availability,

 bookList : { name: string, author: string, availability: boolean }[] = [
    {
      "name": "Famous Five",
      "author": "Enid Blyton",
      "availability": true
    },
    {
      "name": "Harry Potter",
      "author": "J. K. Rowling",
      "availability": true
    },
    {
      "name": "Hamlet",
      "author": "William Shakespeare",
      "availability": false    },
    {
      "name": "Sherlock Holmes",
      "author": "Arthur Conan Doyle",
      "availability": true
    },
  ]

Now lets change app.component.html file to show availability and I want to show available book cards in light green and not available books in light red. So I will change it as below.

 <div class="card container lib-book-card" *ngFor="let Book of bookList"
        [ngStyle]="{'background-color':Book.availability ? '#58e87a' : '#ff82a3' }">
        <h3> {{Book.name}}</h3>
        <p>{{Book.author}}</p>
        <p>Availability : {{Book.availability}}</p>
    </div>

if we check the statement inside [ngStyle] it will set background color to #58e57 which is light green if the availability is true. Else it will set it to #ff82a3, Further you can add more styling inside this array by comma separation. So now our application will display colors according to availability,

Next we will discuss about ngClass

ngClass is used to add css classes to elements once a condition becomes true. For example let’s change card div in app.component.html file.

  <div class="card container lib-book-card" *ngFor="let Book of bookList" 
 [ngStyle]="{'background-color':Book.availability ? '#58e87a' : '#ff82a3' }"        
[ngClass] = "{'card-not-available': !Book.availability}"> 

This will add the css class ‘card-not-available’ to the element wen the book is not available. ( ‘!’ in-front of the Book.availability denote NOT). Now we want to create the class to be bound. So lets go to app.component.css and create that class.

.card-not-available{
    opacity: 0.6;
}

So what this will do is when the book is not available it will reduce the opacity to 0.6 which is 60% and our website will be like below.

To wrap up this session lets have a quick look up what we have studied in this session. We have learned there are three types of directives in angular namely components, sturctural directives and attribute directives. We have learned two types from each and how to use them.

All of these directives are inbuilt directives. So why don’t we go and create our own directive. That is exactly we are doing in the next session. Let’s meet again with custom directives.

Comment here