Angular2 Power Tools

Setup

Stash away any items not needed for this lab

git stash

Checkout the repo at the start tag

git checkout tags/lab/powertools/start -b feature/powertools-lab

Start the local angular-cli server:

ng serve

Start the Data Server in new tab/console (if not already running)

npm run start-api

you should see: NG Live Development Server is running on http://localhost:4200.

http://localhost:4200

A login should load! Let's get to work!

Templates

What is a template?

In other technologies:

Java/JSP

<%@ taglib uri='/WEB-INF/tlds/template.tld' prefix='template' %>
<html>
   <head>
      <title><template:get name='title'/></title>
   </head>
   <body background='graphics/background.jpg'>
   <table>
      <tr valign='top'><td><template:get name='sidebar'/></td>
         <td>
            <table>
              <% for(int i = 0; i < 10; i++) { %>  
                 <tr><td><%=getMyValue(i)%></td></tr> 
              <% } %> 
            </table>
         </td>
      </tr>
   </table>
</body></html>

Python

<table>
  <%
  for item in items:
    %>
    <tr>
      <th>Name</th>
      <td><%= item.name %></td>
    </tr>
    <%
  %>
</table>

Angular 2:

<template let-message let-last="last" ngFor [ngForOf]="messages">
  <a md-list-item>
      <md-icon md-list-avatar>{{message.icon}}</md-icon>
      <h3 md-line>{{message.title}}</h3>
      <h4 md-line>{{message.firstname}} {{message.lastname}}</h4>
      <p md-line>{{message.description}}</p>
      ...
  </a>
  <md-divider md-inset></md-divider>
</template>

From Angular Documentation:

HTML is the language of the Angular template:

<h1>Hello Angular</h1>

Almost all HTML syntax is valid template syntax. The <script> element is a notable exception; it is forbidden, eliminating the risk of script injection attacks.

Some legal HTML doesn't make much sense in a template. The <html>, <body>, and <base> elements have no useful role. Pretty much everything else is fair game.


NgFor

ngFor is a repeater directive.

Similar behavior as:

for (x in objects) { ... }

Example:

<template ngFor [ngForOf]="messages">

Variation:

<li *ngFor="let message of messages; let i = index">...</li>

ngFor can only be applied to a <template>. *ngFor is the short form that can be applied to any element and the <template> element is created implicitly behind the scene.

A <template> is an HTML5 element and is a mechanism for holding client-side content that is not to be rendered when a page is loaded. (like a hidden container of content)

Let's try it!

Part 1 - NgFor
  • First go to covalent-training/src/app/overview/overview.component.ts

  • On line 12 you see the templateUrl

    @Component({
    selector: 'teradata-overview',
    templateUrl: './overview.component.html',
    styleUrls: ['./overview.component.scss'],
    })
    

    This is the html file that will contain all the template code

  • Let's open it up. Go to covalent-training/src/app/overview/overview.component.html

This is the template file that is used to generate the hard coded messages list

  • Find the section on line 16 that says:
    <md-nav-list>
        <a md-list-item>
           <md-icon md-list-avatar>account_box</md-icon>
           <h3 md-line>Message title goes here</h3>
           <h4 md-line>Firstname Lastname</h4>
           <p md-line>Message description goes here and it can be pretty long. At some point do we want the text to truncate...</p>
        ...
        </a>
    
  • Replace all the hard coded list items between
    <md-nav-list>
    ...
    </md-nav-list>
    
  • To instead be an NgFor repeater like this:

    <md-nav-list>
    <template ngFor [ngForOf]="messages">
      <a md-list-item>
          <md-icon md-list-avatar>account_box</md-icon>
          <h3 md-line>Message title goes here</h3>
          <h4 md-line>Firstname Lastname</h4>
          <p md-line>Message description goes here and it can be pretty long. At some point do we want the text to truncate...</p>
          <div flex="none" class="md-caption tc-grey-600">3 min ago</div>
          <span class="push-left-sm">
            <button md-icon-button [mdMenuTriggerFor]="menu"><md-icon>more_vert</md-icon></button>
            <md-menu #menu="mdMenu" x-position="before">
              <button md-menu-item>
                <md-icon>edit</md-icon>
                <span>Edit</span>
              </button>
              <button md-menu-item>
                <md-icon>cancel</md-icon>
                <span>Delete</span>
              </button>
            </md-menu>
          </span>
      </a>
      <md-divider md-inset></md-divider>
    </template>
    </md-nav-list>
    

    At this point you should have deleted most of what was in lines 38 - 162. Notice all the repeated hard coded md-list-item have been consolidated down to one wrapped by ngFor.

  • Take a look at covalent-training/src/app/overview/overview.component.ts lines 18 and 29. Here you will notice the messages being pulled via http from the messagesServices. On line 18 is the array that holds the data: messages: IMessage[];

  • In covalent-training/src/app/overview/overview.component.html notice the ngForOf that will loop over that same messages array: <template ngFor [ngForOf]="messages">


Part 2 - Interpolation and Expressions

If needed you can checkout at this tag in lab. You don't need to checkout this tag if you successfully completed Part 1.

git checkout tags/lab/powertools/ngfor
What is Interpolation?
  • You use interpolation to weave calculated strings into the text between HTML element tags.

  • Let's try it. Go to covalent-training/src/app/overview/overview.component.ts line 19 and add: title: string = 'messages';

  • Go to covalent-training/src/app/overview/overview.component.html

  • On line 13 change:

    <md-card-title>Messages</md-card-title>
    

    To:

    <md-card-title>{{title}}</md-card-title>
    
  • Notice the Card Title now becomes lowercase: messages

What are Expressions?
  • Expressions are the material between the braces that Angular first evaluates and then converts to a string.

  • Let's try it. Go to covalent-training/src/app/overview/overview.component.html

  • On line 13 change:

    <md-card-title>{{title}}</md-card-title>
    

    To:

    <md-card-title>{{messages ? messages.length : 0}} {{title}} from {{1 + 1}} years ago or more</md-card-title>
    
  • Notice the Card Title now becomes: 10 messages from 2 years ago or more

  • Let's break this apart

    • We are displaying the length of the messages array in covalent-training/src/app/overview/overview.component.ts line 18
    • We are using displaying the title from covalent-training/src/app/overview/overview.component.ts line 19
    • And finally we are evaluating the expression 1 + 1 and displaying the result 2
ngFor with Interpolation
  • Now let's use Interpolation with the ngFor we created

  • Go to covalent-training/src/app/overview/overview.component.html

  • Starting on line 17 change this:

    <template ngFor [ngForOf]="messages">
     <a md-list-item>
     <md-icon md-list-avatar>account_box</md-icon>
     <h3 md-line>Message title goes here</h3>
     <h4 md-line>Firstname Lastname</h4>
     <p md-line>Message description goes here and it can be pretty long. At some point do we want the text to truncate...</p>
     <div flex="none" class="md-caption tc-grey-600">3 min ago</div>
    
  • To this:

    <template let-message ngFor [ngForOf]="messages">
     <a md-list-item>
     <md-icon md-list-avatar>{{message.icon}}</md-icon>
     <h3 md-line>{{message.title}}</h3>
     <h4 md-line>{{message.user}}</h4>
     <p md-line>{{message.desc}}</p>
     <div flex="none" class="md-caption tc-grey-600">{{message.created}}</div>
    
  • Let's break this apart

    • We added the let-message to the ngFor on the template. This assigns each object when looping through messages to a variable name message.
    • We can now use the message variable inside our Interpolation Expressions
      • {{message.icon}}, {{message.title}}, {{message.user}}, {{message.desc}}, and {{message.created}} are allow evaluated and allow us to display attributes for the message object
  • The end result now displays the list of message objects and their attributes:


Part 3 - NgFor with index

If needed you can checkout at this tag in lab. You don't need to checkout this tag if you successfully completed Part 2.

git checkout tags/lab/powertools/interpolation
What is it?

The index property of the NgFor directive context returns the zero-based index of the item in each iteration.

Similar behavior as:

for (var i = 0; i < list.length; i++) { ... }

Example:

<template let-index="index" ngFor [ngForOf]="messages">

Variation:

<li *ngFor="let message of messages; let i = index">...</li>

(Same reasoning as above)

  • Let's try it. Go to covalent-training/src/app/overview/overview.component.html

  • On line 17 change:

    <template let-message ngFor [ngForOf]="messages">
    

    To:

    <template let-message let-index="index" ngFor [ngForOf]="messages">
    
  • On line 20 change:

    <h3 md-line>{{message.title}}</h3>
    

    To:

    <h3 md-line>{{index}}. {{message.title}}</h3>
    
  • Notice the index is now displayed next to the title on each row:


Part 4 - NgIf and Last

If needed you can checkout at this tag in lab. You don't need to checkout this tag if you successfully completed Part 3.

git checkout tags/lab/powertools/ngforwithindex
What is NgIf?
  • You can add or remove an element from the DOM by applying an NgIf directive to that element

Similar behavior as:

if(somethingTrue) { ... }
What is Last?

A variable within ngFor that is set to a boolean value indicating whether the item is the last one in the iteration.

  • Let's try it. Go to covalent-training/src/app/overview/overview.component.html

  • On line 17 change:

    <template let-message let-index="index" ngFor [ngForOf]="messages">
    

    To:

    <template let-message let-index="index" let-last="last" ngFor [ngForOf]="messages">
    
  • On line 38 change:

    <md-divider md-inset></md-divider>
    

    To:

    <md-divider *ngIf="!last" md-inset></md-divider>
    

To note: unlike other hiding techniques when using CSS, ngIf completely removes the element from the DOM

By adding this ngIf that checks to see if we aren't on the last element, we no longer get the a double line at the end:

Before:

After:


Part 5 - Pipes

If needed you can checkout at this tag in lab. You don't need to checkout this tag if you successfully completed Part 4.

git checkout tags/lab/powertools/ngifandlast
What is a Pipe?
  • (|) The result of an expression might require some transformation before you're ready to use it in a binding. For example, you might display a number as a currency, force text to uppercase, or change a date to a specific format

  • Let's try it. Go to covalent-training/src/app/overview/overview.component.html

  • On line 23 change:

    <div flex="none" class="md-caption tc-grey-600">{{message.created}}</div>
    

    To:

    <div flex="none" class="md-caption tc-grey-600">{{message.created | date:'medium'}}</div>
    

This takes the message.created date and formats it to 'yMMMdjms' (e.g. Sep 3, 2010, 12:05:08 PM)

  • There are several date options you can pass in besides medium:

results matching ""

    No results matching ""