5. Template Syntax

Interpolation:

<p>My favorite technology is {{ myTechnology }}</p>

<h1>{{ title }}</h1>

<img src="{{ imageUrl }}" class="img-round" alt="image">

<p>The sum of 2 + 2 is {{ 2 + 2 }}</p>

<p>The sum of 2 + 2 is not {{ 2 + 2 + getNumber() }}</p>

Expression Context:

{{ title }}

<span [hidden]="isUnchanged">changed</span>

  <!-- let technology is template input variable -->
  <div *ngFor="let technology of technologies">{{ technology.name }}</div>
  <!-- #technologyName is template reference variable -->
  <input #technologyName (keyup)="0"> {{ technologyName.value }}

Template Statements:

<button (click)="delete()">Delete</button>

Statement Context:

<button (click)="onSave($event)">Save</button>

 <form #technologyForm="ngForm" (ngSubmit)="onSubmit(technologyForm)">
 <input>
 <button type="submit">submit</button>
 </form>

HTML6 and/or HTML7 standards, a new element or component:

<app-technology-detail></app-technology-detail>

Data Binding:

<button [disabled]="isUnchanged">Save</button>

Property Binding(notice square brackets):

<img [src]="imageUrl" class="img-round" alt="image">
<app-technology-detail [technology]="myTechnology"></app-technology-detail>
<div [ngClass]="{'special': isSpecial }">my polymer princess</div>

Event Binding(notice parentheses):

<button (click)="onSave()">Save</button>
<app-technology-detail (newVersionRequest)="newTechnology($event)"></app-technology-detail>
<div (myClick)="clicked=$event">Click me</div> {{ clicked }}

Two-Way Binding:

<input [(ngModel)]="name"> {{ name }}

Attribute Binding(the exception, we are all exceptions and exceptional):

<button [attr.aria-label]="help">Help</button>

Class Binding:

<div [class.special]="isSpecial">we are all special</div>

Style Binding:

<button [style.color]="isSpecial ? 'red' : 'green'">Write Angular Code With Style</button>

One-time String Initialization:

<app-technology-detail prefix="You are my princess" [technology]="myTechnology"></app-technology-detail>

Property Binding Or Interpolation:

<img [src]="imageUrl" class="img-round" alt="princess image">
<img src="{{ imageUrl }}" class="img-round" alt="princess image">

<h1>{{ title }}</h1>
<h1 [innerHTML]="title"></h1>

Content Security(Angular sanitizes HTML):

<p><span>{{ evilScript }}</span></p>
<p><span [innerHTML]="evilScript"></span></p>

evilScript = 'Template <script>Protractor Style Guide; testing best practices with protractor.</script>Syntax';

Attribute Binding(revisited):

            <table border="3">
                <tr><td [attr.colspan]="1 + 1">One-Two</td></tr>
                <tr><td>Three</td><td>Four</td></tr>
            </table>

            <button [attr.aria-label]="actionName">{{ actionName }} with Aria</button>

Class Binding(revisited):

<div [class]="special">she is special</div>

<div [class.special]="isSpecial">this class binding is special</div>
<div class="special" [class.special]="!isSpecial">this one is not so special</div>

<div [ngClass]="special">ngClass is special</div>

Style Binding(revisited):

<button [style.color]="isSpecial ? 'red' : 'green'">Red</button>
<button [style.background-color]="canSave ? 'cyan' : 'grey'">Save</button>

<button [style.font-size.em]="isSpecial ? 3 : 1">Big</button>
<button [style.fontSize.%]="!isSpecial ? 150 : 50">Small</button>

<button [ngStyle]="special">Write Angular Code With Style</button>

Event Binding(revisited):

  <button (click)="onSave()">Save Her</button>

  <button on-click="onSave()">Save Canonical Form</button>
  <div (myClick)="clickMessage=$event">Click Me With myClick</div> {{ clickMessage }}
  <input [value]="myTechnology" (input)="myTechnology=$event.target.value">{{ myTechnology }}

Custom Events with EventEmitter:

<p>
{{ prefix }}  {{ technology }}
</p>
<button (click)="newVersion()">New Version</button>

export class TechnologyDetailComponent {
  @Input() prefix: string;
  @Input() technology: string;
  @Output() newVersionRequest = new EventEmitter<string>();

  newVersion() {
    this.newVersionRequest.emit('Angular 6');
  }

}

  <app-technology-detail [technology]="myTechnology" (newVersionRequest)="newVersion($event)">
          </app-technology-detail>

  newVersion(payload) {
    console.log(payload);
  }

Two-Way Binding:

import { Component, EventEmitter, Input, Output } from '@angular/core';

@Component({
  selector: 'app-sizer',
  template: `
      <div>
            <button (click)="decrease()" title="smaller">-</button>
            <button (click)="increase()" title="bigger">+</button>
            <label [style.font-size.px]="size">FontSize: {{ size }}px</label>
      </div>
  `
})
export class SizerComponent {
    @Input() size: number | string;
    @Output() sizeChange = new EventEmitter<number>();


    decrease() { this.resize(-1); }
    increase() { this.resize(+1); }

    resize(delta: number) {
      this.size = Math.min(42, Math.max(8, +this.size + delta));
      this.sizeChange.emit(this.size);
    }

}


<app-sizer [(size)]="mySizePx"></app-sizer>
<div [style.font-size.px]="mySizePx">Resizable Text</div>

 mySizePx = 15;

Angular Desugars SizerComponent To This:

<app-sizer [size]="mySizePx" (sizeChange)="mySizePx=$event"></app-sizer>

Built-In Directives

Attribute Directives

  1. NgClass
  2. NgStyle
  3. NgModel

NgClass:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
        <h1>{{ title }}</h1>
          <div class="left">
          <div [ngClass]="isSpecial">This class binding is special</div>
          <div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special</div>
          </div>
          <div class="right">
            <img [src]="imageUrl" class="img-round" alt="princess image">
          </div>
  `,
  styles: [`.mySpecial { color: red; }
            .saveable { color: green; }
            .modified { font-family: "Brush Script MT"; }
            .special { font-weight: bold; font-size: x-large; }
            `]
})
export class AppComponent {
  title = 'Tour of Technologies';
  imageUrl = '../assets/polymer6.jpg';
  isSpecial = 'mySpecial';
  canSave = true;
  isUnchanged = false;
  currentClasses: {};
  setCurrentClasses() {
    this.currentClasses = {
      'saveable': this.canSave,
      'modified': !this.isUnchanged,
      'special': this.isSpecial
    };
  }

  constructor() {
    this.setCurrentClasses();
  }

}

NgStyle:

  <div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">
                      This div is x-large.
  </div>

    <div [ngStyle]="currentStyles">
                      This div is initially italic, normal weight, and extra large (24px).
    </div>

    setCurrentStyles() {
    this.currentStyles = {
      'font-style': this.canSave ? 'italic' : 'normal',
      'font-weight': !this.isUnchanged ? 'bold' : 'normal',
      'font-size': this.isSpecial ? '24px' : '12px'
    };
  }

NgModel:

<input [(ngModel)]="myTechnology"> {{ myTechnology }}

<input [value]="myTechnology" (input)="myTechnology=$event.target.value"> {{ myTechnology }}

<input [ngModel]="myTechnology" (ngModelChange)="myTechnology=$event"> {{ myTechnology }}

<input [ngModel]="myTechnology" (ngModelChange)="setUpperCase($event)"> {{ myTechnology }}

Structural Directives

  1. NgIf
  2. NgFor
  3. NgSwitch

NgIf:

<app-technology-detail [technology]="technology.name" *ngIf="technology.isActive">
</app-technology-detail>

Show/Hide:

  <!-- isSpecial is true -->
  <div [class.hidden]="!isSpecial">Show with class</div>
  <div [class.hidden]="isSpecial">Hide with class</div>

  <!--TechnologyDetail is in the DOM but hidden -->
  <app-technology-detail [technology]="myTechnology" [class.hidden]="isSpecial"></app-technology-detail>

  <div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div>
  <div [style.display]="isSpecial ? 'none' : 'block'">Hide with style</div>

Guard Against Null:

            <div *ngIf="myTechnology">Greet {{ myTechnology }}</div>
            <div *ngIf="nullTechnology">Greet {{ nullTechnology }}></div>

NgFor:

<div *ngFor="let technology of technologies">{{ technology.name }}</div>

  <app-technology-detail *ngFor="let technology of technologies" [technology]="technology.name">
  </app-technology-detail>

*ngFor with index:

  <div *ngFor="let technology of technologies; let i = index;">
              {{ i + 1 }} - {{ technology.name }}
  </div>

*ngFor with trackBy:

<div *ngFor="let technology of technologies; trackBy: trackByTechnologies">
              ({{ technology.id }}) {{ technology.name }}
        </div>

 trackByTechnologies(index: number, technology: Technology) {
    console.log(technology.id);
    return technology.id;
  }

NgSwitch:

  <div [ngSwitch]="currentTechnology.emotion">
   <app-awesome-technology *ngSwitchCase="'awesome'" [technology]="currentTechnology"></app-awesome-technology>
   <app-happy-technology *ngSwitchCase="'happy'" [technology]="currentTechnology"></app-happy-technology>
   <app-confused-technology *ngSwitchCase="'confused'" [technology]="currentTechnology"></app-confused-technology>
   <div *ngSwitchCase="'confused'">Are you as confused as {{ currentTechnology.name }}?</div>
   <app-unknown-killer-technology *ngSwitchDefault [technology]="currentTechnology"></app-unknown-killer-technology>
  </div>

  import { Component, Input } from '@angular/core';
import { Technology } from './app.component';

@Component({
  selector: 'app-awesome-technology',
  template: `Wow. You like {{ technology.name }}. What an awesome technology ... just like you.`
})
export class AwesomeTechnologyComponent {
  @Input() technology: Technology;
}

@Component({
  selector: 'app-happy-technology',
  template: `You are a happy technology {{ technology.name }}! May the sun always shine over you.`
})
export class HappyTechnologyComponent {
  @Input() technology: Technology;
}

@Component({
  selector: 'app-confused-technology',
  template: `Are you as confused as {{ technology.name }}?`
})
export class ConfusedTechnologyComponent {
  @Input() technology: Technology;
}

@Component({
  selector: 'app-unknown-killer-technology',
  template: `{{ message }}`
})
export class UnknownKillerTechnologyComponent {
  @Input() technology: Technology;
  get message() {
    return this.technology && this.technology.name ? `${ this.technology.name } is strange and mysterious.`
    : 'Are you feeling indecisive?';
  }
}

export const technologySwitchComponents = [ AwesomeTechnologyComponent, HappyTechnologyComponent,
  ConfusedTechnologyComponent, UnknownKillerTechnologyComponent ];

Template Reference Variables (#var):

  <input #phone placeholder="phone number">
  <button (click)="callPhone(phone.value)">Call</button>

            <form (ngSubmit)="onSubmit(technologyForm)" #technologyForm="ngForm">
                <div class="form-group">
                      <label for="name">Name
                        <input class="form-control" name="name" required [(ngModel)]="currentTechnology">
                      </label>
                </div>
                <button type="submit" [disabled]="!technologyForm.form.valid">Submit</button>
          </form>
          <div [hidden]="!technologyForm.form.valid">
              {{ submitMessage }}
          </div>

          submitMessage = '';
          onSubmit(techForm) {
          this.submitMessage = JSON.stringify(techForm.value);
  }

            <input ref-fax placeholder="fax number">
            <button (click)="callFax(fax.value)">Fax</button>

@Input && @Output:

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-technology-detail',
  template: `
            <p>
              {{ technology }}
            </p>
            <button (click)="newVersion()">New Version</button>
  `
})
export class TechnologyDetailComponent {
  @Input() technology: string;
  @Output() newVersionRequest = new EventEmitter<string>();

  newVersion() {
    this.newVersionRequest.emit('Angular 6');
  }

}

Alternatively:

import { Component, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-technology-detail',
  template: `
            <p>
              {{ technology }}
            </p>
            <button (click)="newVersion()">New Version</button>
  `,
  inputs: ['technology'],
  outputs: ['newVersionRequest']
})
export class TechnologyDetailComponent {
  newVersionRequest = new EventEmitter<string>();

  newVersion() {
    this.newVersionRequest.emit('Angular 6');
  }

}

AppComponent:

<app-technology-detail [technology]="myTechnology"
                                   (newVersionRequest)="newVersion($event)">
            </app-technology-detail>
            {{ message }}

message = '';
  newVersion(payload) {
    this.message = payload;
  }

Aliasing Input/Output Properties:

<div (myClick)="clickMessage=$event">Click with myClick</div>
                  {{ clickMessage }}

@Output('myClick') clicks = new EventEmitter<string>();

@Directive({
  selector: '[myClick]',
  outputs: ['clicks:myClick']
  })

Pipes:

<div>myTechnology through uppercase pipe: {{ myTechnology | uppercase }}</div>

<div>myTechnology through pipe chain: {{ myTechnology | uppercase | lowercase }}</div>

<div>Birthdate: {{ myTechnology.birthdate | date:'longDate' }}</div>

<div>{{ myTechnology | json }}</div>

Safe Navigation Operator(formerly Elvis Operator):

<div>My Technology's name is {{ myTechnology?.name }}</div>

Non-Null Assertion Operator:

              <div *ngIf="myTechnology">
                    My technology's name is {{ myTechnology!.name }}
              </div>

LikeComponent:

import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-like',
  template: `
      <p>The will to win is nothing without the will to prepare.</p>
      <p>Likes: {{ likes }}</p>
        <button class="btn btn-primary"
        [class.btn-danger]="isSelected" (click)="onClick()">Like</button>
  `
})
export class LikeComponent {
  @Input() likes = 0;
  isSelected = false;

  onClick() {
    this.isSelected = !this.isSelected;
    this.likes += (this.isSelected) ? 1 : -1;
  }

}

Property Binding (Square Bracket Notation):

    <div class="col">
          <h2 [textContent]="title"></h2>
            <img class="w-100 p-3 rounded-circle" [src]="imageUrl" />
        </div>

    title = 'List of Technologies';
    imageUrl = './assets/polymer1.jpg';

Attribute Binding:

        <table>
                  <tr>
                      <td [attr.colspan]="colSpan">this column spans 4 columns</td>
                  </tr>
       </table>

       colSpan = 4;

Class Binding:

<button class="btn btn-danger" [class.active]="isActive">Save Her</button>

isActive = true;

Style Binding:

<button [style.backgroundColor]="isActive ? 'red' : 'green'">Save Her</button>

isActive = true;

Event Binding:

          <div (click)="onDivClicked()">
              <button class="btn btn-success" (click)="onSave($event)">Save Her</button>
          </div>

          onDivClicked() {
            console.log('div was clicked');
          }
          onSave(event) {
            event.stopPropagation();
            console.log('save button was clicked', event);
          }

Event Filtering:

  <input #box (keyup.enter)="onKey(box.value)" (keyup)="onKey(box.value)" />
          {{ message }}

  message = '';
  onKey(value: string) {
    this.message += value + '|';
  }

Template Reference Variable:

  <input #text (keyup.enter)="onKey(text.value)" />
          {{ message }}

  message = '';
  onKey(text: string): void {
    this.message = text;
  }

Two Way Binding:

<input [(ngModel)]="message" />
          {{ message }}

results matching ""

    No results matching ""