Template Syntax

Interpolation
Expression context
Statement context
Mental Model
Buttons
Properties vs. Attributes

Property Binding
Attribute Binding
Class Binding
Style Binding

Event Binding
Two-way Binding

Directives
NgModel (two-way) Binding
NgClass Binding
NgStyle Binding
NgIf
NgFor
NgFor with index
NgFor with trackBy
NgSwitch

Template reference variables
Inputs and outputs
Pipes
Safe navigation operator ?.
Non-null assertion operator !.
Enums
SVG Templates

Interpolation

My current hero is {{ currentHero.name }}

{{ title }} {{ hero.name }}

The sum of 1 + 1 is {{ 1 + 1 }}

The sum of 1 + 1 is not {{ 1 + 1 + getVal() }}

top

Expression context

Component expression context ({{title}}, [hidden]="isUnchanged")

{{ title }} changed

Template input variable expression context (let hero)

@for (hero of heroes; track hero) {
{{ hero.name }}
}

Template reference variable expression context (#heroInput)

Type something: {{ heroInput.value }}
top

Statement context

Component statement context ( (click)="onSave() )

Template $event statement context

Template input variable statement context (let hero)

@for (hero of heroes; track hero) { }

Template reference variable statement context (#heroForm)

...
top

New Mental Model

Mental Model


Mental Model






click me
{{ clicked }}

Hero Name: {{ name }}




Special


top

Property vs. Attribute (img examples)



icon villain-image top

Buttons





top

Property Binding

[ngClass] binding to the classes property

interpolated image of {{ currentHero.name }} is the interpolated image.

is the property bound image.

"{{ title }}" is the interpolated title.

"" is the property bound title.

"{{evilTitle}}" is the interpolated evil title.

"" is the property bound evil title.

top

Attribute Binding

One-Two
FiveSix



top

Class Binding

Bad curly special
Bad curly
The class binding is special
This one is not so special
top

Style Binding

top

Event Binding

click with myClick
{{clickMessage}}

Click me
Click me too!
top

Two-way Binding

Resizable Text

De-sugared two-way binding

top

NgModel (two-way) Binding

Result: {{ currentHero.name }}

without NgModel
[(ngModel)]
(ngModelChange)="...name=$event"
(ngModelChange)="setUppercaseName($event)" top

NgClass Binding

currentClasses is {{ currentClasses | json }}

This div is initially saveable, unchanged, and special

| |

This div should be {{ canSave ? "": "not"}} saveable, {{ isUnchanged ? "unchanged" : "modified" }} and, {{ isSpecial ? "": "not"}} special after clicking "Refresh".


This div is special
Bad curly special
Curly special
top

NgStyle Binding

This div is x-large or smaller.

[ngStyle] binding to currentStyles - CSS property names

currentStyles is {{currentStyles | json}}

This div is initially italic, normal weight, and extra large (24px).

| |

This div should be {{ canSave ? "italic": "plain"}}, {{ isUnchanged ? "normal weight" : "bold" }} and, {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".
top

NgIf Binding

@if (isActive) { } @if (currentHero) {
Hello, {{ currentHero.name }}
} @if (nullHero) {
Hello, {{ nullHero.name }}
} Add {{currentHero.name}} with template
Hero Detail removed from DOM (via template) because isActive is false
Show with class
Hide with class
Show with style
Hide with style
top

NgFor Binding

@for (hero of heroes; track hero) {
{{ hero.name }}
}

@for (hero of heroes; track hero) { }
top

*ngFor with index

with semi-colon separator

@for (hero of heroes; track hero; let i = $index) {
{{ i + 1 }} - {{ hero.name }}
}

with comma separator

@for (hero of heroes; track hero; let i = $index) {
{{ i + 1 }} - {{ hero.name }}
}
top

*ngFor trackBy

without trackBy

@for (hero of heroes; track hero) {
({{ hero.id }}) {{ hero.name }}
} @if (heroesNoTrackByCount) {
Hero DOM elements change #{{ heroesNoTrackByCount }} without trackBy
}

with trackBy

@for (hero of heroes; track trackByHeroes($index, hero)) {
({{ hero.id }}) {{ hero.name }}
} @if (heroesWithTrackByCount) {
Hero DOM elements change #{{heroesWithTrackByCount}} with trackBy
}



with trackBy and semi-colon separator

@for (hero of heroes; track trackByHeroes($index, hero)) {
({{ hero.id }}) {{ hero.name }}
}

with trackBy and comma separator

@for (hero of heroes; track hero) {
({{ hero.id }}) {{ hero.name }}
}

with trackBy and space separator

@for (hero of heroes; track hero) {
({{ hero.id }}) {{ hero.name }}
}

with generic trackById function

@for (hero of heroes; track hero) {
({{ hero.id }}) {{ hero.name }}
}
top

NgSwitch Binding

Pick your favorite hero

@for (h of heroes; track h) { }
@switch (currentHero.emotion) { @case ('happy') { } @case ('sad') { } @case ('confused') { } @case ('confused') {
Are you as confused as {{ currentHero.name }}?
} @default { } }
top

Template reference variables

Example Form

top

Inputs and Outputs

icon
myClick2
{{ clickMessage2 }} top

Pipes

Title through uppercase pipe: {{ title | uppercase }}
Title through a pipe chain: {{ title | uppercase | lowercase }}
Birthdate: {{ currentHero.birthdate | date:'longDate' }}
{{ currentHero | json }}
Birthdate: {{ (currentHero.birthdate | date:'longDate') | uppercase }}
Price: {{ product.price | currency:'USD':'symbol' }}
top

Safe navigation operator ?.

The title is {{ title }}
The current hero's name is {{ currentHero.name }}
The current hero's name is {{ currentHero.name }}
@if (nullHero) {
The null hero's name is {{ nullHero.name }}
}
The null hero's name is {{ nullHero && nullHero.name }}
The null hero's name is {{ nullHero?.name }}
top

Non-null assertion operator !.

@if (hero) {
The hero's name is {{ hero!.name }}
}
top

$any type cast function $any( ).

The hero's marker is {{ $any(hero).marker }}
Undeclared members is {{ $any(this).member }}
top

Enums in binding

The name of the Color.Red enum is {{ Color[Color.Red] }}.
The current color is {{ Color[color] }} and its number is {{ color }}.

top

SVG Templates

top