© Venkata Keerti Kotaru 2020
V. K. KotaruAngular for Material Designhttps://doi.org/10.1007/978-1-4842-5434-9_6

6. Angular: Directives

Venkata Keerti Kotaru1 
(1)
Hyderabad, India
 

Angular helps build views that are declarative and use HTML markup. Angular helps reuse most HTML elements and features. It helps extend functionality, making it a powerful framework.

This chapter describes various types of directives. It lists some of Angular’s most popular built-in directives. The directives help code conditional logic in the HTML template, iterate through the collections, and apply the styles dynamically.

Directives

Angular provides the ability to augment the HTML template and provide additional features and functionalities. Directives play an important role. There are three categories of directives in Angular.

  • Components : This type of directive allows you to create custom elements. It is a powerful feature that provides maximum reusability of the Angular application. It is arguably the most widely used feature in Angular. There is an entire chapter dedicated to components in this book.

  • Structural directives: This type of directive allows you to customize and modify the structure of a view. For example, a list of the superheroes is a view. You may use a directive to iterate through an available list of superheroes and show them in an ordered list. As another example, imagine that the contact information about a superhero is hidden by default. You can show it conditionally when the user requests it.

    Conditionally showing or hiding contact information is a structural change to the superhero view. Iterating through the superhero list and showing the available superheroes in a list is structural.

  • Attribute directives: Attribute directives augment an element’s behavior and view. It may add additional functionalities to the element. ngStyle is an example of an attribute directive. A section in this chapter describes this directive.

  • This chapter discusses the built-in directives in Angular. They are powerful and used often in building web applications.

Using the ng-template Directive in the HTML Template

ng-template is an Angular element. You may use it to refer to a block in an HTML template. It is useful for showing or hiding a section of the component or for using a block of HTML in one or more places in the template.

You may use a template reference variable to provide a name for a block of HTML. In Listing 6-1, a component that shows superhero information, a section of contact information is wrapped in ng-template (see lines 8 to 13). A template reference variable is provided to refer to the contents (see #heroContactDetails in line 8).

Note

Refer to the @ViewChild() implementation in Chapter 4 to learn about using a template reference variable in a TypeScript file component.

The block of HTML in lines 8 to 13 do not show when the page loads. It is a block of HTML waiting to be used. Refer to line 5, which has the ngTemplateOutlet structural directive. It refers to heroContactDetails, the template reference variable defined in line 8. Hence, the block of HTML for the superhero contact information is rendered in line 5.

We placed the template between the <hr> elements to highlight that the location template has been rendered. The result is shown in Figure 6-1.
1.   <div class="hero">
2.      <div>
3.       <h2>Chhotta Bheem</h2>
4.       <div>Loves laddu. Grows strong everyday</div>
5.       <hr /><div *ngTemplateOutlet="heroContactDetails"></div> <hr />
6.      </div>
7.    </div>
8.    <ng-template #heroContactDetails>
9.
10.        <h3>Contact Details</h3>
11.        Email: [email protected]
12.        Meet him in Dholakpur Villege in India.
13.  </ng-template>
Listing 6-1

Usage on ng-template in the Superhero Component

../images/475625_1_En_6_Chapter/475625_1_En_6_Fig1_HTML.jpg
Figure 6-1

Contact information template

Using if…else Conditions in the HTML Template

To incorporate conditional logic in the HTML template, we can use the ∗ngIf directive. It is a structural directive. Imagine that we want to show or hide part of a component conditionally. Let’s enhance Listing 6-2. Consider showing the superhero contact information when the user explicitly selects a check box. By default (or when the user unselects the check box), contact information is hidden.

We can achieve this functionality with the ∗ngIf directive. In line 1 of Listing 6-2, when the showContacts value is true, the contact details template is shown. The contact details template is written in lines 2 to 7.
1. <div *ngIf="showContacts; then contactDetails"></div>
2. <ng-template #contactDetails>
3.   <hr />
4.   <h3>Contact Details</h3>
5.   Email: [email protected]
6.   Meet him in Dholakpur Villege in India.
7. </ng-template>
Listing 6-2

Show Elements When Conditional

Note

Structural directives are prefixed with an asterisk (*).

In Listing 6-3, the value of showContacts is set by a check box with ngModel data binding. When the user selects or unselects the check box, the data binding updates ∗ngIf. We can show or hide the contact information on the fly.
<input class="specialInput" type="checkbox" [(ngModel)]="showContacts"> Show contact details
Listing 6-3

Check Box to Switch the True/False Condition

Let’s improve this sample code by adding an else condition. Show a message that the contact information is hidden when the check box is unselected. Listing 6-4 adds an else condition to the directive. Note the else condition that uses the hiddenText template. The HTML code between lines 8 and 11 is for the message text.

Notice the syntax to use if…else with the ∗ngIf directive in the first line (see Listing 6-4). We use two template reference variables: the first variable, contactDetails, followed by the “then” keyword, when the condition is true; and the second variable, hiddenText, followed by the “else” keyword, when the condition is false.
1. <div *ngIf="showContacts; then contactDetails else hiddenText"></div>
2.  <ng-template #contactDetails>
3.    <hr />
4.    <h3>Contact Details</h3>
5.    Email: [email protected]
6.    Meet him in Dholakpur Villege in India.
7.  </ng-template>
8   <ng-template #hiddenText>
9.    <hr />
10.   *Contact information is hidden.
11. </ng-template>
Listing 6-4

Else Condition for Superhero Contact Details

Note

Listing 6-4 uses a Boolean variable, showContacts, which can be true/false. Any conditional statement that returns true/false can be used with *ngIf.

Using the ng-container Directive in the HTML Template

ng-container wraps HTML elements. Typically, HTML elements are wrapped in elements like <div>, <span>, <p>, and so forth; however, applications might use specific styles that are predefined when these elements are used. For example, there could be a global style on a web application that applies certain margins and padding to a div element. This style might interfere when attempting to wrap a set of elements in your component. To address this scenario, you could use ng-container. It does not show as an element in HTML when rendered in a browser; hence, there is no style applied that interferes with the set of elements it encapsulates.

Refer to the first lines of Listing 6-3 and Listing 6-4. A div is used as a placeholder for the conditional logic; either #contactDetails template or #hiddenText template is shown in its place. If the div uses a global style, it is applied here as well. You may use ng-container instead of a div here.

You may simplify the code sample another level by showing the content within the ng-container instead of using a separate template for it. This removes #contactDetails as a separate section (see Listing 6-5).
1.    <ng-container *ngIf="showContacts else hiddenText">
2.      <hr />
3.      <h3>Contact Details</h3>
4.      Email: [email protected]
5.      Meet him in Dholakpur Villege in India.
6.    </ng-container>
7.    <ng-template #hiddenText>
8.        <hr />
9.        *Contact information is hidden.
10.   </ng-template>
Listing 6-5

Simplified Conditional Logic

Note that ∗ngIf="showContacts; then contactDetails else hiddenText" is simplified to ∗ngIf="showContacts else hiddenText".

Figure 6-2 shows the result.
../images/475625_1_En_6_Chapter/475625_1_En_6_Fig2_HTML.jpg
Figure 6-2

Contact details shown/hidden conditionally

In Figure 6-3, the ng-container does not show as an element in the rendered HTML.
../images/475625_1_En_6_Chapter/475625_1_En_6_Fig3_HTML.jpg
Figure 6-3

HTML rendered while using ng-container

Using a Switch Case in the HTML Template

∗ngIf is useful for a simple if/else condition. Use the following directives if the condition includes comparing multiple values.
  • ngSwitch: The variable to be compared with values.

  • ngSwitchCase: One of the many values to be compared. Typically, a series of ngSwitchCase directives are used.

  • ngSwitchDefault: The default value when none of the values matches.

To better understand usage, consider birthplace as an input text field. If the user inputs places on Earth, we show an Earthling label. For alien places, we show an Alien label. If it does not match any known values, show a default message to provide a known value. Listing 6-6 uses the ngSwitch, ngSwitchCase, and ngSwitchDefault directives.
1.      Provide a birth place: <input type="text" [(ngModel)]="birthplace">
2.    <div [ngSwitch]="birthplace">
3.      <span *ngSwitchCase="'Dholakpur'">Earthling</span>
4.      <span *ngSwitchCase="'Kryptonopolis'">Alien</span>
5.      <span *ngSwitchCase="'Asgard'">Alien</span>
6.      <span *ngSwitchCase="'New York'">Earthling</span>
7.      <span *ngSwitchCase="'Gotham'">Earthling</span>
8.      <span *ngSwitchCase="'Dholakpur'">Earthling</span>
9.      <span *ngSwitchDefault>Provide a known birthplace</span>
10.    </div>
Listing 6-6

Switch/Case to Conditionally Verify Multiple Values

Refer to line 2 in Listing 6-7. The ngSwitch directive checks the equality condition in the birthplace variable. If the value provided in the text field (line 1) matches any value provided between lines 3 and 8, the respective value is shown. The ngSwitch variable is compared to the ngSwitchCase value. In the sample, we are using string values. The values Dholakpur, Kryptonopolis, and so forth, are not data bound with a variable.

A default message, “Provide a known birthplace”, is shown when none of the values match (see line 9). Figure 6-4 shows the result.
../images/475625_1_En_6_Chapter/475625_1_En_6_Fig4_HTML.jpg
Figure 6-4

Result of using Switch/Case

Iterate Through an Array in the HTML Template

Use the ∗ngForOf structural directive to iterate through an array of elements. Consider an example. There is a list of superheroes to show in the component. We can iterate through the objects to process and show each of them. For simplicity, let’s consider using an array of simple strings, as shown in Listing 6-7.
@Component({ //  Removed code for brevity })
export class HomeComponent implements OnInit {
  superheroes =[
    "Spiderman",
    "Chhota Bheem",
    "Superman",
    "Batman"
  ]
  constructor() { }
  ngOnInit() {  }
}
Listing 6-7

List of Superheroes in the TypeScript File Component

A shorthand form of ∗ngForOf directive is often used. Listing 6-8 iterates through the superheroes and shows the values in a list. We create a hero variable that represents each hero string with let hero of superheroes. Considering that a hero is a simple string, we show the value with interpolation data binding ({{hero}}).

Note

If superheroes is an array of objects, the hero local variable would be an individual object in the array. You may use the hero.fieldName syntax to show a field.

  <div>
    <li *ngFor="let hero of superheroes"> {{hero}} </li>
  </div>
Listing 6-8

Iterate Through Superheroes in HTML Template

Figure 6-5 shows the result.
../images/475625_1_En_6_Chapter/475625_1_En_6_Fig5_HTML.jpg
Figure 6-5

List of superheroes

Listing 6-9 is the shorthand form of ngFor. This form simplifies the syntax. We can expand the ∗ngFor shorthand form to ngForOf syntax (see Listing 6-9).
    <ng-template ngFor let-hero [ngForOf]="superheroes">
      <li > {{hero}} </li>
    </ng-template>
Listing 6-9

ngForOf with Superheroes Array

Local Variables with ngFor

You may use the following local variables with the directive.
  • index: Stores a zero-based index number for each iteration

  • first: Sets to true if it is the first iteration.

  • last: Sets to true if it is the last iteration.

  • even: Sets to true if it is an even iteration.

  • odd: Sets to true if it is an odd iteration.

Listing 6-10 makes use of these variables. In the first line, each local variable is aliased to be used; for example, index is i. Line 2 shows item numbers. We increment by one because it is a zero-based index.

In lines 3 to 6, there is a conditional check if a local variable value is set to true. If yes, we show the string identifying whether it is a first item or a last item, or an even item or an odd item.
1.    <div *ngFor="let hero of superheroes; index as i; first as isFirst; last as isLast; even as isEven; odd as isOdd">
2.    {{i+1}}. {{hero}}
3.    <ng-template [ngIf]="isFirst">(first)</ng-template>
4.    <ng-template [ngIf]="isLast">(last)</ng-template>
5.    <ng-template [ngIf]="isEven">(even)</ng-template>
6.    <ng-template [ngIf]="isOdd">(odd)</ng-template>
7.  </div>
Listing 6-10

Show Local Variables

Note

Note [ngIf]="expressionOrBoolean". The *ngIf="expressionOrBoolean" directive syntax does not show the value as the page loads. With the latter, the template is expected to be referenced and used elsewhere.

Figure 6-6 shows the result.
../images/475625_1_En_6_Chapter/475625_1_En_6_Fig6_HTML.jpg
Figure 6-6

List of superheroes with local variables on ngFor

Change Styles On the Fly with ngStyle

We use the ngStyle directive to update the styles on an element on the fly. Typically, styles are predefined, and we do not need a directive to update them. However, consider a requirement to update the style as the user chooses to select and unselect values on the screen. We can use ngStyle, an attribute directive for grouping styles, to apply on the element. Figure 6-7 is a use case.
../images/475625_1_En_6_Chapter/475625_1_En_6_Fig7_HTML.jpg
Figure 6-7

ngStyle for updating styles on the fly

The options include bold, italic, and strike-through.

Use the ngStyle directive to apply the combined derived styles on the title element, Chhotta Bheem. In Listing 6-11, the titleStyle variable holds the grouped style values.
<div [ngStyle]="titleStyle">Chhotta Bheem</div>
Listing 6-11

ngStyle Usage

Listing 6-12 groups the styles (in the TypeScript file component) and exposes them to the HTML template with a getter function. The getter function is used in Listing 6-12.
@Component({// removed code for brevity})
export class HomeComponent implements OnInit {
  isItalic = false;
  isBold = false;
  isStrikeThrough = false;
  get titleStyle(){
    return {
      'text-decoration': this.isStrikeThrough ? 'line-through' : 'none',
      'font-weight': this.isBold ? 'bold': 'normal',
      'font-style': this.isItalic ? 'italic': 'normal',
      'font-size': '24px'
    };
  }
  constructor() { }
  ngOnInit() {  }
}
Listing 6-12

titleStyle, a Variable That Groups Styles for the Superhero Title

The text-decoration, font-weight, and font-style styles are applied conditionally. They are based on the isItalic, isBold, and isStrikeThrough class variables. These variables are used with ngModel two-way data binding from the template HTML file. The text-decoration, font-weight, and font-style names match the CSS style names. They are wrapped in a JSON object (see Listing 6-13).
1. <div>
2.      <input class="specialInput" type="checkbox" [(ngModel)]="isBold"> Bold
3. </div>
4. <div>
5.   <input class="specialInput" type="checkbox" [(ngModel)]="isItalic"> Italic
6. </div>
7. <div>
8.  <input class="specialInput" type="checkbox" [(ngModel)]="isStrikeThrough"> 9.    Strike-through
10. </div>
11. <div [ngStyle]="titleStyle">Chhotta Bheem</div>
Listing 6-13

HTML Template with ngStyle

The ngStyle attribute directive was applied in line 11. When the user changes values, the component rerenders to apply the new styles with the ngStyle directive. It translates styles in the JSON object to the styles on the element. Figure 6-8 shows the directive applying selected CSS styles on the element.
../images/475625_1_En_6_Chapter/475625_1_En_6_Fig8_HTML.jpg
Figure 6-8

ngStyle modifies styles on the DOM

Conclusion

This chapter introduced you to directives. It described the types of component directives, structural directives, and attribute directives.

It described the purpose and usage of two Angular elements: ng-template and ng-container.

It lists a few important and often-used directives that help code conditional logic in a template: ∗ngIf and ∗ngSwitch with ∗ngSwitchCase and ∗ngSwitchDefault.

The chapter also described ∗ngForOf, which helps you to iterate through arrays.

Exercise

Create a list screen that shows a dinosaur’s listing. Also iterate through the following dinosaur family list to show check boxes next to each item. When the user selects a family, show only the dinosaurs that belong to the selected family.
  • Abelisauridae

  • Noasauridae

  • Megalosauridae

Reference

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.36.141