Displaying Data

The live example / download example demonstrates all of the syntax and code snippets described in this page.

Showing component properties with interpolation

The easiest way to display a component property is to bind the property name through interpolation. With interpolation, you put the property name in the view template, enclosed in double curly braces: {{myHero}}.
When you bootstrap with the AppComponent class (in main.ts), Angular looks for a <app-root> in the index.html, finds it, instantiates an instance of AppComponent, and renders it inside the <app-root> tag.

Template inline or template file?

You can store your component's template in one of two places. You can define it inline using the template property, or you can define the template in a separate HTML file and link to it in the component metadata using the @Component decorator's templateUrl property.

Showing an array property with *ngFor

To display a list of heroes, begin by adding an array of hero names to the component and redefine myHero to be the first name in the array.
src/app/app.component.ts (li)
      

<li *ngFor="let hero of heroes">
  {{ hero }}
</li>

In this case, ngFor is displaying an array, but ngFor can repeat items for any iterable object.

Conditional display with NgIf

Sometimes an app needs to display a view or a portion of a view only under specific circumstances.
src/app/app.component.ts (message)
      

<p *ngIf="heroes.length > 3">There are many heroes!</p>

Summary

Now you know how to use:
  • Interpolation with double curly braces to display a component property.
  • ngFor to display an array of items.
  • A TypeScript class to shape the model data for your component and display properties of that model.
  • ngIf to conditionally display a chunk of HTML based on a boolean expression.

2.Template Syntax


The Angular application manages what the user sees and can do, achieving this through the interaction of a component class instance (the component) and its user-facing template.
In Angular, the component plays the part of the controller/viewmodel in model-view-viewmodel (MVVM), and the template represents the view.

2.1-HTML in templates

HTML is the language of the Angular template. Almost all HTML syntax is valid template syntax

Interpolation ( {{...}} )

You met the double-curly braces of interpolation, {{ and }}, early in your Angular education.
src/app/app.component.html
      
<p>My current hero is {{currentHero.name}}</p>

Template expressions

A template expression produces a value. Angular executes the expression and assigns it to a property of a binding target; the target might be an HTML element, a component, or a directive.
The interpolation braces in {{1 + 1}} surround the template expression 1 + 1. In the property binding section below, a template expression appears in quotes to the right of the = symbol as in [property]="expression".

Expression context

The expression context is typically the component instance. In the following snippets, the title within double-curly braces and the isUnchanged in quotes refer to properties of the AppComponent.
src/app/app.component.html
      
{{title}}
<span [hidden]="isUnchanged">changed</span>

An expression may also refer to properties of the template's context such as a template input variable (let hero) or a template reference variable (#heroInput).
src/app/app.component.html
      
<div *ngFor="let hero of heroes">{{hero.name}}</div>
<input #heroInput> {{heroInput.value}}
    

The context for terms in an expression is a blend of the template variables, the directive's context object (if it has one), and the component's members. If you reference a name that belongs to more than one of these namespaces, the template variable name takes precedence, followed by a name in the directive's context, and, lastly, the component's member names.

Template statements

A template statement responds to an event raised by a binding target such as an element, component, or directive. You'll see template statements in the event binding section, appearing in quotes to the right of the = symbol as in (event)="statement".
src/app/app.component.html
      
<button (click)="deleteHero()">Delete hero</button>
    

A template statement has a side effect. That's the whole point of an event. It's how you update application state from user action.

2.2-Binding syntax: An overview

Data binding is a mechanism for coordinating what users see, with application data values.
Angular provides many kinds of data binding.

Binding types can be grouped into three categories distinguished by the direction of data flow: from the source-to-view, from view-to-source, and in the two-way sequence: view-to-source-to-view:

Interpolation,Property,Attribute,Class,Style:

is One-way from data source to view target
{{expression}}
[target]="expression"
bind-target="expression"


Event:
One-way from view target to data source       
(target)="statement"
on-target="statement"

Two-way:
has two-way data direction
[(target)]="expression" 
bindon-target="expression"       

Binding types other than interpolation have a target name to the left of the equal sign, either surrounded by punctuation ([], ()) or preceded by a prefix (bind-, on-, bindon-).
The target name is the name of a property. It may look like the name of an attribute but it never is. To appreciate the difference, you must develop a new way to think about template HTML.

The first binding you meet might look like this:
src/app/app.component.html
      
<!-- Bind button disabled state to `isUnchanged` property -->
<button [disabled]="isUnchanged">Save</button>
    

You'll get to that peculiar bracket notation in a moment. Looking beyond it, your intuition suggests that you're binding to the button's disabled attribute and setting it to the current value of the component's isUnchanged property.

Binding targets

The target of a data binding is something in the DOM. Depending on the binding type, the target can be an (element | component | directive) property, an (element | component | directive) event, or (rarely) an attribute name. The following table summarizes:

  • Property: Element property, Component property, Directive property 
  • Event: Element event, Component event, Directive event 
  • Two-way: Event and property 
  • Attribute: Attribute (the exception) 
  • Class class property 
  • Style style property 

example: src/app/app.component.html
      

<button [style.color]="isSpecial ? 'red' : 'green'">

Property binding ( [property] )

Write a template property binding to set a property of a view element. The binding sets the property to the value of a template expression.
The most common property binding sets an element property to a component property value. An example is binding the src property of an image element to a component's heroImageUrl property:
src/app/app.component.html
      

<img [src]="heroImageUrl">

One-way in

People often describe property binding as one-way data binding because it flows a value in one direction, from a component's data property into a target element property.

Binding target

An element property between enclosing square brackets identifies the target property. The target property in the following code is the image element's src property.
src/app/app.component.html
      
<img [src]="heroImageUrl">
    
Some people prefer the bind- prefix alternative, known as the canonical form:
src/app/app.component.html
      

<img bind-src="heroImageUrl">

Return the proper type

The template expression should evaluate to the type of value expected by the target property. Return a string if the target property expects a string. Return a number if the target property expects a number. Return an object if the target property expects an object.
The hero property of the HeroDetail component expects a Hero object, which is exactly what you're sending in the property binding:
src/app/app.component.html
      

<app-hero-detail [hero]="currentHero"></app-hero-detail>

Remember the brackets

The brackets tell Angular to evaluate the template expression. If you omit the brackets, Angular treats the string as a constant and initializes the target property with that string. It does not evaluate the string!

Property binding or interpolation?

You often have a choice between interpolation and property binding. The following binding pairs do the same thing:
src/app/app.component.html
      
<p><img src="{{heroImageUrl}}"> is the <i>interpolated</i> image.</p>
<p><img [src]="heroImageUrl"> is the <i>property bound</i> image.</p>

<p><span>"{{title}}" is the <i>interpolated</i> title.</span></p>
<p>"<span [innerHTML]="title"></span>" is the <i>property bound</i> title.</p>
    

Interpolation is a convenient alternative to property binding in many cases.

Attribute, class, and style bindings

The template syntax provides specialized one-way bindings for scenarios less well suited to property binding.

Attribute binding

You can set the value of an attribute directly with an attribute binding.
for example, Bind [attr.colspan] to a calculated value:
src/app/app.component.html
      
<table border=1>
  <!--  expression calculates colspan=2 -->
  <tr><td [attr.colspan]="1 + 1">One-Two</td></tr>

  <!-- ERROR: There is no `colspan` property to set!
    <tr><td colspan="{{1 + 1}}">Three-Four</td></tr>
  -->

  <tr><td>Five</td><td>Six</td></tr>
</table>

Class binding

You can add and remove CSS class names from an element's class attribute with a class binding.
Class binding syntax resembles property binding. Instead of an element property between brackets, start with the prefix class, optionally followed by a dot (.) and the name of a CSS class: [class.class-name].
src/app/app.component.html
      

<!-- reset/override all class names with a binding  -->
<div class="bad curly special"
     [class]="badCurly">Bad curly</div>
src/app/app.component.html
      

<!-- toggle the "special" class on/off with a property -->
<div [class.special]="isSpecial">The class binding is special</div>

<!-- binding to `class.special` trumps the class attribute -->
<div class="special"
     [class.special]="!isSpecial">This one is not so special</div>

Style binding

You can set inline styles with a style binding.
Style binding syntax resembles property binding. Instead of an element property between brackets, start with the prefix style, followed by a dot (.) and the name of a CSS style property: [style.style-property].
src/app/app.component.html
      

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

Event binding ( (event) )

The bindings directives you've met so far flow data in one direction: from a component to an element.
The following event binding listens for the button's click events, calling the component's onSave() method whenever a click occurs:
src/app/app.component.html
      
<button (click)="onSave()">Save</button>

Target event

A name between parentheses — for example, (click) — identifies the target event. In the following example, the target is the button's click event.
src/app/app.component.html
      
<button (click)="onSave()">Save</button>
    
Some people prefer the on- prefix alternative, known as the canonical form:
src/app/app.component.html
      
<button on-click="onSave()">On Save</button>
    
Element events may be the more common targets, but Angular looks first to see if the name matches an event property of a known directive, as it does in the following example:
src/app/app.component.html
      
<!-- `myClick` is an event on the custom `ClickDirective` -->
<div (myClick)="clickMessage=$event" clickable>click with myClick</div>
    
The myClick directive is further described in the section on aliasing input/output properties.
If the name fails to match an element event or an output property of a known directive, Angular reports an “unknown directive” error.

$event and event handling statements

In an event binding, Angular sets up an event handler for the target event.
When the event is raised, the handler executes the template statement. The template statement typically involves a receiver, which performs an action in response to the event, such as storing a value from the HTML control into a model.

The binding conveys information about the event, including data values, through an event object named $event.

Consider this example:
src/app/app.component.html
      
<input [value]="currentHero.name"
       (input)="currentHero.name=$event.target.value" >
    
This code sets the input box value property by binding to the name property. To listen for changes to the value, the code binds to the input box's input event. When the user makes changes, the input event is raised, and the binding executes the statement within a context that includes the DOM event object, $event.

To update the name property, the changed text is retrieved by following the path $event.target.value.

Two-way binding ( [(...)] )

You often want to both display a data property and update that property when the user makes changes.
On the element side that takes a combination of setting a specific element property and listening for an element change event.
Angular offers a special two-way data binding syntax for this purpose, [(x)]. The [(x)] syntax combines the brackets of property binding, [x], with the parentheses of event binding, (x).
[( )] = banana in a box
Visualize a banana in a box to remember that the parentheses go inside the brackets.

The [(x)] syntax is easy to demonstrate when the element has a settable property called x and a corresponding event named xChange. Here's a SizerComponent that fits the pattern. It has a size value property and a companion sizeChange event:
Here's an example in which the AppComponent.fontSizePx is two-way bound to the SizerComponent:
src/app/app.component.html (two-way-1)
      
<app-sizer [(size)]="fontSizePx"></app-sizer>
<div [style.font-size.px]="fontSizePx">Resizable Text</div>
    

The AppComponent.fontSizePx establishes the initial SizerComponent.size value. Clicking the buttons updates the AppComponent.fontSizePx via the two-way binding. The revised AppComponent.fontSizePx value flows through to the style binding, making the displayed text bigger or smaller.

src/app/app.component.html (two-way-2)
      
<app-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></app-sizer>
    
The $event variable contains the payload of the SizerComponent.sizeChange event. Angular assigns the $event value to the AppComponent.fontSizePx when the user clicks the buttons.

Built-in directives

Earlier versions of Angular included over seventy built-in directives. The community contributed many more, and countless private directives have been created for internal applications.

This segment reviews some of the most frequently used built-in directives, classified as either attribute directives or structural directives.

Built-in attribute directives

Attribute directives listen to and modify the behavior of other HTML elements, attributes, properties, and components. They are usually applied to elements as if they were HTML attributes, hence the name.
Many details are covered in the Attribute Directives guide. Many NgModules such as the RouterModule and the FormsModule define their own attribute directives. This section is an introduction to the most commonly used attribute directives:

  • NgClass - add and remove a set of CSS classes
  • NgStyle - add and remove a set of HTML styles
  • NgModel - two-way data binding to an HTML form element
 Here's an example:
src/app/app.component.html (NgModel-1)
      
<input [(ngModel)]="currentHero.name">

FormsModule is required to use ngModel

Before using the ngModel directive in a two-way data binding, you must import the FormsModule and add it to the NgModule's imports list. Learn more about the FormsModule and ngModel in the Forms guide.

Built-in structural directives

Structural directives are responsible for HTML layout. They shape or reshape the DOM's structure, typically by adding, removing, and manipulating the host elements to which they are attached.
The deep details of structural directives are covered in the Structural Directives guide where you'll learn:
This section is an introduction to the common structural directives:

  • NgIf - conditionally add or remove an element from the DOM
  • NgSwitch - a set of directives that switch among alternative views
  • NgForOf - repeat a template for each item in a list

Template input variables

The let keyword before hero creates a template input variable called hero. The NgForOf directive iterates over the heroes array returned by the parent component's heroes property and sets hero to the current item from the array during each iteration.
You reference the hero input variable within the NgForOf host element (and within its descendants) to access the hero's properties. Here it is referenced first in an interpolation and then passed in a binding to the hero property of the <hero-detail> component.
src/app/app.component.html
      
<div *ngFor="let hero of heroes">{{hero.name}}</div>
<app-hero-detail *ngFor="let hero of heroes" [hero]="hero"></app-hero-detail>
    

Learn more about template input variables in the Structural Directives guide.

Template reference variables ( #var )

A template reference variable is often a reference to a DOM element within a template. It can also be a reference to an Angular component or directive or a web component.
Use the hash symbol (#) to declare a reference variable. The #phone declares a phone variable on an <input> element.
src/app/app.component.html
      
<input #phone placeholder="phone number">
    
You can refer to a template reference variable anywhere in the template. The phone variable declared on this <input> is consumed in a <button> on the other side of the template
src/app/app.component.html
      
<input #phone placeholder="phone number">

<!-- lots of other elements -->

<!-- phone refers to the input element; pass its `value` to an event handler -->
<button (click)="callPhone(phone.value)">Call</button>

How a reference variable gets its value

In most cases, Angular sets the reference variable's value to the element on which it was declared. In the previous example, phone refers to the phone number <input> box. The phone button click handler passes the input value to the component's callPhone method. But a directive can change that behavior and set the value to something else, such as itself. The NgForm directive does that.

Template reference variable warning notes

A template reference variable (#phone) is not the same as a template input variable (let phone) such as you might see in an *ngFor. Learn the difference in the Structural Directives guide.
The scope of a reference variable is the entire template. Do not define the same variable name more than once in the same template. The runtime value will be unpredictable.
You can use the ref- prefix alternative to #. This example declares the fax variable as ref-fax instead of #fax.
src/app/app.component.html
      

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

Input and Output properties

An Input property is a settable property annotated with an @Input decorator. Values flow into the property when it is data bound with a property binding
An Output property is an observable property annotated with an @Output decorator. The property almost always returns an Angular EventEmitter. Values flow out of the component as events bound with an event binding.

You can only bind to another component or directive through its Input and Output properties.






















The pipe operator ( | )

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 filter a list and sort it.
Angular pipes are a good choice for small transformations such as these. Pipes are simple functions that accept an input value and return a transformed value. They're easy to apply within template expressions, using the pipe operator (|):
src/app/app.component.html
      
<div>Title through uppercase pipe: {{title | uppercase}}</div>
    
The pipe operator passes the result of an expression on the left to a pipe function on the right.
You can chain expressions through multiple pipes:
src/app/app.component.html
      
<!-- Pipe chaining: convert title to uppercase, then to lowercase -->
<div>
  Title through a pipe chain:
  {{title | uppercase | lowercase}}
</div>
    
And you can also apply parameters to a pipe:
src/app/app.component.html
      
<!-- pipe with configuration argument => "February 25, 1970" -->
<div>Birthdate: {{currentHero?.birthdate | date:'longDate'}}</div>
    
The json pipe is particularly helpful for debugging bindings:
src/app/app.component.html (pipes-json)
      
<div>{{currentHero | json}}</div>
    
The generated output would look something like this
      
{ "id": 0, "name": "Hercules", "emotion": "happy",
  "birthdate": "1970-02-25T08:00:00.000Z",
  "url": "http://www.imdb.com/title/tt0065832/",
  "rate": 325 }   

3.User Input

User actions such as clicking a link, pushing a button, and entering text raise DOM events. This page explains how to bind those events to component event handlers using the Angular event binding syntax.
Run the live example / download example.

Binding to user input events

You can use Angular event bindings to respond to any DOM event. Many DOM events are triggered by user input. Binding to these events provides a way to get input from the user.
To bind to a DOM event, surround the DOM event name in parentheses and assign a quoted template statement to it.
The following example shows an event binding that implements a click handler:
src/app/click-me.component.ts
      
<button (click)="onClickMe()">Click me!</button>
    

The (click) to the left of the equals sign identifies the button's click event as the target of the binding. The text in quotes to the right of the equals sign is the template statement, which responds to the click event by calling the component's onClickMe method.

Get user input from the $event object

DOM events carry a payload of information that may be useful to the component. This section shows how to bind to the keyup event of an input box to get the user's input after each keystroke.
The following code listens to the keyup event and passes the entire event payload ($event) to the component event handler.
src/app/keyup.components.ts (template v.1)
      
template: `
  <input (keyup)="onKey($event)">
  <p>{{values}}</p>
`
    
When a user presses and releases a key, the keyup event occurs, and Angular provides a corresponding DOM event object in the $event variable which this code passes as a parameter to the component's onKey() method.
src/app/keyup.components.ts (class v.1)
      
export class KeyUpComponent_v1 {
  values = '';

  onKey(event: any) { // without type info
    this.values += event.target.value + ' | ';
  }
}
    
The properties of an $event object vary depending on the type of DOM event. For example, a mouse event includes different information than an input box editing event.

All standard DOM event objects have a target property, a reference to the element that raised the event. In this case, target refers to the <input> element and event.target.value returns the current contents of that element.

Type the $event

The example above casts the $event as an any type. That simplifies the code at a cost. There is no type information that could reveal properties of the event object and prevent silly mistakes.
The following example rewrites the method with types:
src/app/keyup.components.ts (class v.1 - typed )
      
export class KeyUpComponent_v1 {
  values = '';


  onKey(event: KeyboardEvent) { // with type info
    this.values += (<HTMLInputElement>event.target).value + ' | ';
  }
}
    

The $event is now a specific KeyboardEvent. Not all elements have a value property so it casts target to an input element.

Get user input from a template reference variable

There's another way to get the user data: use Angular template reference variables. These variables provide direct access to an element from within the template. To declare a template reference variable, precede an identifier with a hash (or pound) character (#).

Key event filtering (with key.enter)

The (keyup) event handler hears every keystroke. Sometimes only the Enter key matters, because it signals that the user has finished typing. One way to reduce the noise would be to examine every $event.keyCode and take action only when the key is Enter.

On blur

In the previous example, the current state of the input box is lost if the user mouses away and clicks elsewhere on the page without first pressing Enter. The component's value property is updated only when the user presses Enter.
To fix this issue, listen to both the Enter key and the blur event.

4.Lifecycle Hooks

A component has a lifecycle managed by Angular.
Angular creates it, renders it, creates and renders its children, checks it when its data-bound properties change, and destroys it before removing it from the DOM.
Angular offers lifecycle hooks that provide visibility into these key life moments and the ability to act when they occur.

A directive has the same set of lifecycle hooks.

Component lifecycle hooks overview

Directive and component instances have a lifecycle as Angular creates, updates, and destroys them. Developers can tap into key moments in that lifecycle by implementing one or more of the lifecycle hook interfaces in the Angular core library.
Each interface has a single hook method whose name is the interface name prefixed with ng. For example, the OnInit interface has a hook method named ngOnInit() that Angular calls shortly after creating the component:

Lifecycle sequence

After creating a component/directive by calling its constructor, Angular calls the lifecycle hook methods in the following sequence at specific moments:
ngOnChanges()
ngOnInit()
ngDoCheck()
ngAfterContentInit()
ngAfterContentChecked()
ngAfterViewInit()
ngAfterViewChecked()
ngOnDestroy()

Interfaces are optional (technically)

The interfaces are optional for JavaScript and Typescript developers from a purely technical perspective. The JavaScript language doesn't have interfaces. Angular can't see TypeScript interfaces at runtime because they disappear from the transpiled JavaScript.
Fortunately, they aren't necessary. You don't have to add the lifecycle hook interfaces to directives and components to benefit from the hooks themselves.

Angular instead inspects directive and component classes and calls the hook methods if they are defined. Angular finds and calls methods like ngOnInit(), with or without the interfaces.

Spying OnInit and OnDestroy

Go undercover with these two spy hooks to discover when an element is initialized or destroyed.
This is the perfect infiltration job for a directive. The heroes will never know they're being watched.
Kidding aside, pay attention to two key points:
  1. Angular calls hook methods for directives as well as components.

  2. A spy directive can provide insight into a DOM object that you cannot change directly. Obviously you can't touch the implementation of a native <div>. You can't modify a third party component either. But you can watch both with a directive.

The sneaky spy directive is simple, consisting almost entirely of ngOnInit() and ngOnDestroy() hooks that log messages to the parent via an injected LoggerService.

OnInit()

Use ngOnInit() for two main reasons:
  1. To perform complex initializations shortly after construction.
  2. To set up the component after Angular sets the input properties.

OnDestroy()

Put cleanup logic in ngOnDestroy(), the logic that must run before Angular destroys the directive.

OnChanges()

Angular calls its ngOnChanges() method whenever it detects changes to input properties of the component (or directive). This example monitors the OnChanges hook.

DoCheck()

Use the DoCheck hook to detect and act upon changes that Angular doesn't catch on its own.
Use this method to detect a change that Angular overlooked.

AfterView

The AfterView sample explores the AfterViewInit() and AfterViewChecked() hooks that Angular calls after it creates a component's child views.

AfterContent

The AfterContent sample explores the AfterContentInit() and AfterContentChecked() hooks that Angular calls after Angular projects external content into the component.

Content projection

Content projection is a way to import HTML content from outside the component and insert that content into the component's template in a designated spot.
AngularJS developers know this technique as transclusion.

AfterContent hooks

AfterContent hooks are similar to the AfterView hooks. The key difference is in the child component.
  • The AfterView hooks concern ViewChildren, the child components whose element tags appear within the component's template.
  • The AfterContent hooks concern ContentChildren, the child components that Angular projected into the component.

5.Component Interaction

This cookbook contains recipes for common component communication scenarios in which two or more components share information.

See the live example / download example.

Pass data from parent to child with input binding

HeroChildComponent has two input properties, typically adorned with @Input decorations.
export class HeroChildComponent {
  @Input() hero: Hero;
  @Input('master') masterName: string;
}
The second @Input aliases the child component property name masterName as 'master'.
The HeroParentComponent nests the child HeroChildComponent inside an *ngFor repeater, binding its master string property to the child's master alias, and each iteration's hero instance to the child's hero property.
export class HeroParentComponent {
  heroes = HEROES;
  master = 'Master';
}

    <app-hero-child *ngFor="let hero of heroes"
      [hero]="hero"
      [master]="master">
    </app-hero-child>

Intercept input property changes with a setter

Use an input property setter to intercept and act upon a value from the parent

Intercept input property changes with ngOnChanges()

Detect and act upon changes to input property values with the ngOnChanges() method of the OnChanges lifecycle hook interface.

Parent listens for child event

The child component exposes an EventEmitter property with which it emits events when something happens. The parent binds to that event property and reacts to those events.
The child's EventEmitter property is an output property, typically adorned with an @Output decoration as seen in this VoterComponent:
Clicking a button triggers emission of a true or false, the boolean payload.
The parent VoteTakerComponent binds an event handler called onVoted() that responds to the child event payload $event and updates a counter.
The framework passes the event argument—represented by $event—to the handler method, and the method processes it.

Parent interacts with child via local variable

A parent component cannot use data binding to read child properties or invoke child methods. You can do both by creating a template reference variable for the child element and then reference that variable within the parent template as seen in the following example.
The following is a child CountdownTimerComponent that repeatedly counts down to zero and launches a rocket. It has start and stop methods that control the clock and it displays a countdown status message in its own template.
component-interaction/src/app/countdown-timer.component.ts
      

  1. import { Component, OnDestroy, OnInit } from '@angular/core';
  2.  
  3. @Component({
  4. selector: 'app-countdown-timer',
  5. template: '<p>{{message}}</p>'
  6. })
  7. export class CountdownTimerComponent implements OnInit, OnDestroy {
  8.  
  9. intervalId = 0;
  10. ..
  11. }
The CountdownLocalVarParentComponent that hosts the timer component is as follows:
component-interaction/src/app/countdown-parent.component.ts
      
  1. import { Component } from '@angular/core';
  2. import { CountdownTimerComponent } from './countdown-timer.component';
  3.  
  4. @Component({
  5. selector: 'app-countdown-parent-lv',
  6. template: `
  7. <h3>Countdown to Liftoff (via local variable)</h3>
  8. <button (click)="timer.start()">Start</button>
  9. <button (click)="timer.stop()">Stop</button>
  10. <div class="seconds">{{timer.seconds}}</div>
  11. <app-countdown-timer #timer></app-countdown-timer>
  12. `,
  13. styleUrls: ['../assets/demo.css']
  14. })
  15. export class CountdownLocalVarParentComponent { }
The parent component cannot data bind to the child's start and stop methods nor to its seconds property.
You can place a local variable, #timer, on the tag <countdown-timer> representing the child component. That gives you a reference to the child component and the ability to access any of its properties or methods from within the parent template.

This example wires parent buttons to the child's start and stop and uses interpolation to display the child's seconds property.

Parent calls an @ViewChild()

The local variable approach is simple and easy. But it is limited because the parent-child wiring must be done entirely within the parent template. The parent component itself has no access to the child.
You can't use the local variable technique if an instance of the parent component class must read or write child component values or must call child component methods.
When the parent component class requires that kind of access, inject the child component into the parent as a ViewChild.
The following example illustrates this technique with the same Countdown Timer example. Neither its appearance nor its behavior will change. The child CountdownTimerComponent is the same as well.

The switch from the local variable to the ViewChild technique is solely for the purpose of demonstration.

Parent and children communicate via a service

A parent component and its children share a service whose interface enables bi-directional communication within the family.
The scope of the service instance is the parent component and its children. Components outside this component subtree have no access to the service or their communications.

This MissionService connects the MissionControlComponent to multiple AstronautComponent children.

6.Component Styles

Angular applications are styled with standard CSS. That means you can apply everything you know about CSS stylesheets, selectors, rules, and media queries directly to Angular applications.
Additionally, Angular can bundle component styles with components, enabling a more modular design than regular stylesheets.
This page describes how to load and apply these component styles.

You can run the live example / download example in Stackblitz and download the code from there.

Using component styles

For every Angular component you write, you may define not only an HTML template, but also the CSS styles that go with that template, specifying any selectors, rules, and media queries that you need.
One way to do this is to set the styles property in the component metadata. The styles property takes an array of strings that contain CSS code.

Style scope

The styles specified in @Component metadata apply only within the template of that component.

Special selectors

Component styles have a few special selectors from the world of shadow DOM style scoping (described in the CSS Scoping Module Level 1 page on the W3C site). The following sections describe these selectors.

Loading component styles

There are several ways to add styles to a component:
  • By setting styles or styleUrls metadata.
  • Inline in the template HTML.
  • With CSS imports.

The scoping rules outlined earlier apply to each of these loading patterns.

styles: ['h1 { font-weight: normal; }']

 styleUrls: ['./hero-app.component.css']

  template: `
    <style>
      button {
        background-color: white;
        border: 1px solid #777;
      }
    </style>
    <h3>Controls</h3>
    <button (click)="activate()">Activate</button>

You can also write <link> tags into the component's HTML template.
<link rel="stylesheet" href="../assets/hero-team.component.css">

CSS @imports

You can also import CSS files into the CSS files using the standard CSS @import rule. For details, see @import on the MDN site.
In this case, the URL is relative to the CSS file into which you're importing.
src/app/hero-details.component.css (excerpt)
      

/* The AOT compiler needs the `./` to show that this is local */
@import './hero-details-box.css';

Non-CSS style files

If you're building with the CLI, you can write style files in sass, less, or stylus and specify those files in the @Component.styleUrls metadata with the appropriate extensions (.scss, .less, .styl) as in the following example:
      
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
...
    
The CLI build process runs the pertinent CSS preprocessor.
When generating a component file with ng generate component, the CLI emits an empty CSS styles file (.css) by default. You can configure the CLI to default to your preferred CSS preprocessor as explained in the CLI documentation.

Style strings added to the @Component.styles array must be written in CSS because the CLI cannot apply a preprocessor to inline styles.

7.Angular Elements Overview

Angular elements are Angular components packaged as custom elements, a web standard for defining new HTML elements in a framework-agnostic way.
Custom elements are a Web Platform feature currently supported by Chrome, Opera, and Safari, and available in other browsers through polyfills (see Browser Support). A custom element extends HTML by allowing you to define a tag whose content is created and controlled by JavaScript code. The browser maintains a CustomElementRegistry of defined custom elements (also called Web Components), which maps an instantiable JavaScript class to an HTML tag.
The @angular/elements package exports a createCustomElement() API that provides a bridge from Angular's component interface and change detection functionality to the built-in DOM API.

Transforming a component to a custom element makes all of the required Angular infrastructure available to the browser. Creating a custom element is simple and straightforward, and automatically connects your component-defined view with change detection and data binding, mapping Angular functionality to the corresponding native HTML equivalents.

Use the createCustomElement() function to convert a component into a class that can be registered with the browser as a custom element.

Transforming components to custom elements

Angular provides the createCustomElement() function for converting an Angular component, together with its dependencies, to a custom element. The function collects the component's observable properties, along with the Angular functionality the browser needs to create and destroy instances, and to detect and respond to changes.

Mapping

A custom element hosts an Angular component, providing a bridge between the data and logic defined in the component and standard DOM APIs. Component properties and logic maps directly into HTML attributes and the browser's event system.

Example: A Popup Service

Previously, when you wanted to add a component to an app at runtime, you had to define a dynamic component. The app module would have to list your dynamic component under entryComponents, so that the app wouldn't expect it to be present at startup, and then you would have to load it, attach it to an element in the DOM, and wire up all of the dependencies, change detection, and event handling, as described in Dynamic Component Loader.
Using an Angular custom element makes the process much simpler and more transparent, by providing all of the infrastructure and framework automatically—all you have to do is define the kind of event handling you want. (You do still have to exclude the component from compilation, if you are not going to use it in your app.)

The Popup Service example app (shown below) defines a component that you can either load dynamically or convert to a custom element.

Typings for custom elements

Generic DOM APIs, such as document.createElement() or document.querySelector(), return an element type that is appropriate for the specified arguments. For example, calling document.createElement('a') will return an HTMLAnchorElement, which TypeScript knows has an href property. Similarly, document.createElement('div') will return an HTMLDivElement, which TypeScript knows has no href property.
When called with unknown elements, such as a custom element name (popup-element in our example), the methods will return a generic type, such as HTMLELement, since TypeScript can't infer the correct type of the returned element.

Custom elements created with Angular extend NgElement (which in turn extends HTMLElement). Additionally, these custom elements will have a property for each input of the corresponding component. For example, our popup-element will have a message property of type string.

8.Dynamic Component Loader

Component templates are not always fixed. An application may need to load new components at runtime.
This cookbook shows you how to use ComponentFactoryResolver to add components dynamically.

See the live example / download example of the code in this cookbook.

The anchor directive

Before you can add components you have to define an anchor point to tell Angular where to insert components.

Loading components

Most of the ad banner implementation is in ad-banner.component.ts. To keep things simple in this example, the HTML is in the @Component decorator's template property as a template string.
The <ng-template> element is where you apply the directive you just made. To apply the AdDirective, recall the selector from ad.directive.ts, ad-host. Apply that to <ng-template> without the square brackets. Now Angular knows where to dynamically load components.

9.Attribute Directives

An Attribute directive changes the appearance or behavior of a DOM element.
Try the Attribute Directive example / download example.

Directives overview

There are three kinds of directives in Angular:
  1. Components—directives with a template.
  2. Structural directives—change the DOM layout by adding and removing DOM elements.
  3. Attribute directives—change the appearance or behavior of an element, component, or another directive.
Components are the most common of the three directives. You saw a component for the first time in the QuickStart guide.
Structural Directives change the structure of the view. Two examples are NgFor and NgIf. Learn about them in the Structural Directives guide.

Attribute directives are used as attributes of elements. The built-in NgStyle directive in the Template Syntax guide, for example, can change several element styles at the same time.

You can tell if @Input is needed by the position of the property name in a binding.
  • When it appears in the template expression to the right of the equals (=), it belongs to the template's component and does not require the @Input decorator.
  • When it appears in square brackets ([ ]) to the left of the equals (=), the property belongs to some other component or directive; that property must be adorned with the @Input decorator.

10.Structural Directives

This guide looks at how Angular manipulates the DOM with structural directives and how you can write your own structural directives to do the same thing.
Try the live example / download example.

What are structural directives?

Structural directives are responsible for HTML layout. They shape or reshape the DOM's structure, typically by adding, removing, or manipulating elements.
As with other directives, you apply a structural directive to a host element. The directive then does whatever it's supposed to do with that host element and its descendants.
Structural directives are easy to recognize. An asterisk (*) precedes the directive attribute name as in this example.
src/app/app.component.html (ngif)
      
<div *ngIf="hero" class="name">{{hero.name}}</div>
    

No brackets. No parentheses. Just *ngIf set to a string.

There are two other kinds of Angular directives, described extensively elsewhere: (1) components and (2) attribute directives.
A component manages a region of HTML in the manner of a native HTML element. Technically it's a directive with a template.
An attribute directive changes the appearance or behavior of an element, component, or another directive. For example, the built-in NgStyle directive changes several element styles at the same time.
You can apply many attribute directives to one host element. You can only apply one structural directive to a host element.

The asterisk (*) prefix

Surely you noticed the asterisk (*) prefix to the directive name and wondered why it is necessary and what it does.
Here is *ngIf displaying the hero's name if hero exists.
src/app/app.component.html (asterisk)
      
<div *ngIf="hero" class="name">{{hero.name}}</div>
    
The asterisk is "syntactic sugar" for something a bit more complicated. Internally, Angular translates the *ngIf attribute into a <ng-template> element, wrapped around the host element, like this.
src/app/app.component.html (ngif-template)
      
<ng-template [ngIf]="hero">
  <div class="name">{{hero.name}}</div>
</ng-template>
    

  • The *ngIf directive moved to the <ng-template> element where it became a property binding,[ngIf].
  • The rest of the <div>, including its class attribute, moved inside the <ng-template> element.

Microsyntax

The Angular microsyntax lets you configure a directive in a compact, friendly string. The microsyntax parser translates that string into attributes on the <ng-template>:
  • The let keyword declares a template input variable that you reference within the template. The input variables in this example are hero, i, and odd. The parser translates let hero, let i, and let odd into variables named, let-hero, let-i, and let-odd.
  • The microsyntax parser takes of and trackBy, title-cases them (of -> Of, trackBy -> TrackBy), and prefixes them with the directive's attribute name (ngFor), yielding the names ngForOf and ngForTrackBy. Those are the names of two NgFor input properties . That's how the directive learns that the list is heroes and the track-by function is trackById.
  • As the NgFor directive loops through the list, it sets and resets properties of its own context object. These properties include index and odd and a special property named $implicit.
  • The let-i and let-odd variables were defined as let i=index and let odd=odd. Angular sets them to the current value of the context's index and odd properties.
  • The context property for let-hero wasn't specified. Its intended source is implicit. Angular sets let-hero to the value of the context's $implicit property which NgFor has initialized with the hero for the current iteration.
  • The API guide describes additional NgFor directive properties and context properties.
  • NgFor is implemented by the NgForOf directive. Read more about additional NgForOf directive properties and context properties NgForOf API reference.
These microsyntax mechanisms are available to you when you write your own structural directives. Studying the source code for NgIf and NgForOf is a great way to learn more.

Template input variable

A template input variable is a variable whose value you can reference within a single instance of the template. There are several such variables in this example: hero, i, and odd. All are preceded by the keyword let.
A template input variable is not the same as a template reference variable, neither semantically nor syntactically.
You declare a template input variable using the let keyword (let hero). The variable's scope is limited to a single instance of the repeated template. You can use the same variable name again in the definition of other structural directives.
You declare a template reference variable by prefixing the variable name with # (#var). A reference variable refers to its attached element, component or directive. It can be accessed anywhere in the entire template.

Template input and reference variable names have their own namespaces. The hero in let hero is never the same variable as the hero declared as #hero.

Prefer the asterisk (*) syntax.

The asterisk (*) syntax is more clear than the desugared form. Use <ng-container> when there's no single element to host the directive.
While there's rarely a good reason to apply a structural directive in template attribute or element form, it's still important to know that Angular creates a <ng-template> and to understand how it works. You'll refer to the <ng-template> when you write your own structural directive.

The <ng-template>

The <ng-template> is an Angular element for rendering HTML. It is never displayed directly. In fact, before rendering the view, Angular replaces the <ng-template> and its contents with a comment.
If there is no structural directive and you merely wrap some elements in a <ng-template>, those elements disappear. That's the fate of the middle "Hip!" in the phrase "Hip! Hip! Hooray!".
src/app/app.component.html (template-tag)
      
<p>Hip!</p>
<ng-template>
  <p>Hip!</p>
</ng-template>
<p>Hooray!</p>
    

Angular erases the middle "Hip!", leaving the cheer a bit less enthusiastic.








You learned

11.Pipes

Every application starts out with what seems like a simple task: get data, transform them, and show them to users. Getting data could be as simple as creating a local variable or as complex as streaming data over a WebSocket.
Introducing Angular pipes, a way to write display-value transformations that you can declare in your HTML.
You can run the live example / download example in Stackblitz and download the code from there.

Using pipes

A pipe takes in data as input and transforms it to a desired output. In this page, you'll use pipes to transform a component's birthday property into a human-friendly date.
src/app/hero-birthday1.component.ts
      
import { Component } from '@angular/core';

@Component({
  selector: 'app-hero-birthday',
  template: `<p>The hero's birthday is {{ birthday | date }}</p>`
})
export class HeroBirthdayComponent {
  birthday = new Date(1988, 3, 15); // April 15, 1988
}
    
Focus on the component's template.
src/app/app.component.html
      
<p>The hero's birthday is {{ birthday | date }}</p>
    

Inside the interpolation expression, you flow the component's birthday value through the pipe operator ( | ) to the Date pipe function on the right. All pipes work this way.

Built-in pipes

Angular comes with a stock of pipes such as DatePipe, UpperCasePipe, LowerCasePipe, CurrencyPipe, and PercentPipe. They are all available for use in any template.