Skip to main content

Directives

Contents

Structural Directives

  • Meant to alter structure of DOM
  • Start with '*' sign

*ngIf

Usage

  • Used to render an element on a given condition
<p *ngIf="counter > 1">
{{ counter }}
</p>
  • *ngIf vs [hidden] and css display : none properties

  • *ngIf Completely remove elements from DOM while the other properties hide the element but it still remains in the DOM tree

  • Example: user id is rendered only if user is not null

<p *ngIf="user">
{{ user.id }}
</p>

Logical operators

*ngIf="a && b"  and
="a || b" or
= "!a" not

Else condition

<div *ngIf="count > 0;else negativeBlock" >
<p>Positive</p>
</div>

<ng-template #negativeBlock>
<p>Negative</p>
</ng-template>

Then condition

<ng-template *ngIf="count > 0;then positiveBlock;else negativeBlock" >
</ng-template>

<ng-template #positiveBlock>
<p>Positive</p>
</ng-template>

<ng-template #negativeBlock>
<p>Negative</p>
</ng-template>

Background working

<div *ngIf="count > 0;else negativeBlock" >
<p>Positive</p>
</div>

<ng-template #negativeBlock>
<p>Negative</p>
</ng-template>

is converted to

<ng-template [ngIf]="count > 0" [ngIfElse]="negativeBlock">
<div >
<p>Positive</p>
</div>
</ng-template>

<ng-template #negativeBlock>
<p>Negative</p>
</ng-template>

*ngFor

Usage

  • Used to iterate DOM elements as an array
<ul>
<li *ngFor="let item of array">
{{ item }}
</li>
</ul>

is converted to

<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>

Access Index

<ul>
<li *ngFor="let item of array; let i=index">
{{ i }}
</li>
</ul>

Options

  • first
  • last
  • even returns true if element is even indexed
  • odd

Example: Specify even, odd elements

<div
*ngFor="let item of items;
let isEven=even;
let isOdd=odd"
>
<ng-template *ngIf="isEven; then evenBlock; else oddBlock">
</ng-template>

<ng-template #evenBlock>Even</ng-template>
<ng-template #oddBlock>Odd</ng-template>
</div>

Output:

Even item 0
Odd item 1
Even item 2
Odd item 3
Even item 4

Re-Rendering

  • List is re-rendered on following occurrences
    • add
    • remove
    • reorder

Optimizing Re-Renders

  • Angular uses reference of objects to re-render only new components added/removed
  • But when using REST API objects change and references change
  • So angular has to re-render entire list
  • There is a way to tell Angular if we have 'unique id' to track in the list items

trackBy

  • Create a function that returns item id
items = [
{
guid : 'item_id_00'
name : 'item_name_00'
},
{
guid : 'item_id_01'
name : 'item_name_01'
}
]

trackElement(index : number, item : any){
if(item){
return item.guid;
}else{
return null
}
}
<ul>
<li
*ngFor="let item of items;
trackBy:trackElement"
>
{{ item }}
</li>
</ul>

Using with non-iterables

Javascript Objects
<ul>
<li *ngFor="let elem of object | values"></li>
</ul>
  • Create a pipe
values.pipe.ts
import { PipeTransform, Pipe } from '@angular/core';

@Pipe(
{
name : 'values'
}
)

export class ValuesPipe implements PipeTransform{
transform(value, args : string[]) : any{
let values = [];
for(let key in value){
values.push(value[key])
}
return values;
}
}
Observables
  • Use async provided by Angular
<ul>
<li *ngFor="let elem of test_observable$ | async>
</ul>

Attribute Directives

  • Change appearance and behaviour of an element or component

ngClass

Using Plain JavaScript

let elem = document.getElementById('exampleDiv');
elem.className = 'example-class'

Using [className] property binding

<!-- example-class => string -->
<div [className]="example-class"></div>
  • Based on condition
<!-- is_positive => boolean, example-class => string -->
<div
[className]="is_positive ? 'example-class' : 'other-class"
>
Positive
</div>
  • Toggle Class on condition
<!-- active_nav_bar => class name, is_active => boolean -->
<div [class.active_nav_bar]="is_active">Nav</div>

Using ngClass

  • Assign a class
<div [ngClass]="'example-class'"></div>
  • Assign multiple class
<div [ngClass]="['example-class', 'is-active']"></div>
  • Based on condition
<!-- example-class => string, contitionA => boolean -->
<div
[ngClass]="{
'example-class' : conditionA,
'is-active' : is_active
}"
>
Nav-Bar
</div>
  • Set classes through TS file
ExampleComponent.HTML
<div [ngClass]="setClass()"></div>
ExampleComponent.TS
setClasses() {
let classes = {
'example-class' : conditionA,
'other-class' : conditionB
};

return classes;
}

ngStyle

Using plain JavaScript

elem = document.getElementById('example-div');
elem.style.color = 'blue';

Using property binding

<!-- blue => string -->
<div [style.color]="blue">

OR define variable in TS file

<!-- primary-color => variable defined in TS file -->
<div [style.color]="primary-color">
primary-color : string = 'blue'
  • Condition based
<!-- isPrimary => boolean, colorA & colorB => strings or variables defined in TS file -->
<div [style.color]="isPrimary ? colorA : colorB">

Using ngStyle

Used to add inline-CSS to elements

<!-- string expression after '=' sign is similar to css expression  -->
<div [ngStyle]="{'color' : 'blue'}">
Text
</div>
  • Condition based
<div
[ngStyle]="{
'color' : conditionA ? colorA : colorB,
'margin' : '8px'
}"
>