Angular's
<ng-template>
element defines a template that is not rendered by default.
See more...
Description
link
With
<ng-template>
, you can define template content that is only being rendered by Angular when you, whether directly or indirectly, specifically instruct it to do so, allowing you to have full control over how and when the content is displayed.
Note that if you wrap content inside an
<ng-template>
without instructing Angular to render it, such content will not appear on a page. For example, see the following HTML code, when handling it Angular won't render the middle "Hip!" in the phrase "Hip! Hip! Hooray!" because of the surrounding
<ng-template>
.
Further information is available in the Usage Notes...
Usage notes
link
Structural Directives
link
One of the main uses for
<ng-template>
is to hold template content that will be used by Structural directives. Those directives can add and remove copies of the template content based on their own logic.
When using the structural directive shorthand, Angular creates an
<ng-template>
element behind the scenes.
TemplateRef
link
<ng-template>
elements are represented as instances of the
TemplateRef
class.
To add copies of the template to the DOM, pass this object to the
ViewContainerRef
method
createEmbeddedView()
.
Template Variables
link
<ng-template>
elements can be referenced in templates using standard template variables.
This is how
<ng-template>
elements are used as
ngIf
else clauses.
Such template variables can be used in conjunction with
ngTemplateOutlet
directives to render the content defined inside
<ng-template>
tags.
Querying
link
A Query (such as
ViewChild
) can find the
TemplateRef
associated to an
<ng-template>
element so that it can be used programmatically; for instance, to pass it to the
ViewContainerRef
method
createEmbeddedView()
.
Context
link
Inside the
<ng-template>
tags you can reference variables present in the surrounding outer template.
Additionally, a context object can be associated with
<ng-template>
elements.
Such an object contains variables that can be accessed from within the template contents via template (
let
and
as
) declarations.
You can define a set of styles together to make up a specific state for animating elements and transitions. These states represent style at certain points in your animations that you can animate to and from. For example, you can animate a state as the starting point to a different state and the end of an animation.
What is a state?
link
A state is the condition of an animation. The Angular state() function takes two parameters: a unique name and a style. There is also an optional parameter.
Why would you want to use state?
link
Aliasing a set of styles and allows you to reference that alias for animations in general. This can make animations more readable or more understandable at a glance. You can give animations a useful and descriptive state name, which allows you to quickly understand the purpose of that animation state.
Use Angular's
state()
function to define different states to call at the end of each transition.
This function takes two arguments:
A unique name like
open
or
closed
and a
style()
function.
Use the
style()
function to define a set of styles to associate with a given state name.
You must use
camelCase
for style attributes that contain dashes, such as
backgroundColor
or wrap them in quotes, such as
'background-color'
.
Angular's
state()
function works with the
style()
function to set CSS style attributes.
In this code snippet, multiple style attributes are set at the same time for the state.
In the
open
state, the button has a height of 200 pixels, an opacity of 1, and a yellow background color.
The web is used by a wide variety of people, including those who have visual or motor impairments.
A variety of assistive technologies are available that make it much easier for these groups to interact with web-based software applications.
Also, designing an application to be more accessible generally improves the user experience for all users.
For an in-depth introduction to issues and techniques for designing accessible applications, see the Accessibility section of the Google's Web Fundamentals.
This page discusses best practices for designing Angular applications that work well for all users, including those who rely on assistive technologies.
For the sample application that this page describes, see the
live example
/ download example
.
Accessibility attributes
link
Building accessible web experience often involves setting Accessible Rich Internet Applications (ARIA) attributes to provide semantic meaning where it might otherwise be missing.
Use attribute binding template syntax to control the values of accessibility-related attributes.
When binding to ARIA attributes in Angular, you must use the
attr.
prefix. The ARIA specification depends specifically on HTML attributes rather than properties of DOM elements.
<!-- Use attr. when binding to an ARIA attribute --><button [attr.aria-label]="myActionLabel">…</button>
NOTE
This syntax is only necessary for attribute
bindings
.
Static ARIA attributes require no extra syntax.
<!-- Static ARIA attributes require no extra syntax --><buttonaria-label="Save document">…</button>
By convention, HTML attributes use lowercase names (
tabindex
), while properties use camelCase names (
tabIndex
).
See the Binding syntax guide for more background on the difference between attributes and properties.
Angular UI components
link
The Angular Material library, which is maintained by the Angular team, is a suite of reusable UI components that aims to be fully accessible.
The Component Development Kit (CDK) includes the
a11y
package that provides tools to support various areas of accessibility.
For example:
LiveAnnouncer
is used to announce messages for screen-reader users using an
aria-live
region.
See the W3C documentation for more information on aria-live regions.
The
cdkTrapFocus
directive traps Tab-key focus within an element.
Use it to create accessible experience for components such as modal dialogs, where focus must be constrained.
For full details of these and other tools, see the Angular CDK accessibility overview.
Augmenting native elements
link
Native HTML elements capture several standard interaction patterns that are important to accessibility.
When authoring Angular components, you should re-use these native elements directly when possible, rather than re-implementing well-supported behaviors.
For example, instead of creating a custom element for a new variety of button, create a component that uses an attribute selector with a native
<button>
element.
This most commonly applies to
<button>
and
<a>
, but can be used with many other types of element.
You can see examples of this pattern in Angular Material:
MatButton
,
MatTabNav
, and
MatTable
.
Using containers for native elements
link
Sometimes using the appropriate native element requires a container element.
For example, the native
<input>
element cannot have children, so any custom text entry components need to wrap an
<input>
with extra elements.
By just including
<input>
in your custom component's template, it's impossible for your component's users to set arbitrary properties and attributes to the
<input>
element.
Instead, create a container component that uses content projection to include the native control in the component's API.
You can see
MatFormField
as an example of this pattern.
Case study: Building a custom progress bar
link
The following example shows how to make a progress bar accessible by using host binding to control accessibility-related attributes.
The component defines an accessibility-enabled element with both the standard HTML attribute
role
, and ARIA attributes.
The ARIA attribute
aria-valuenow
is bound to the user's input.
src/app/progress-bar.component.ts
import{Component,Input}from'@angular/core';/**
* Example progressbar component.
*/@Component({
selector:'app-example-progressbar',template:'<div class="bar" [style.width.%]="value"></div>',
styleUrls:['./progress-bar.component.css'],
host:{// Sets the role for this component to "progressbar"
role:'progressbar',// Sets the minimum and maximum values for the progressbar role.'aria-valuemin':'0','aria-valuemax':'100',// Binding that updates the current value of the progressbar.'[attr.aria-valuenow]':'value',}})exportclassExampleProgressbarComponent{/** Current value of the progressbar. */@Input()value=0;}
In the template, the
aria-label
attribute ensures that the control is accessible to screen readers.
src/app/app.component.html
<label>
Enter an example progress value
<inputtype="number"min="0"max="100"
[value]="progress" (input)="setProgress($event)"></label><!-- The user of the progressbar sets an aria-label to communicate what the progress means. --><app-example-progressbar [value]="progress"aria-label="Example of a progress bar"></app-example-progressbar>
Routing
link
Focus management after navigation
link
Tracking and controlling focus in a UI is an important consideration in designing for accessibility.
When using Angular routing, you should decide where page focus goes upon navigation.
To avoid relying solely on visual cues, you need to make sure your routing code updates focus after page navigation.
Use the
NavigationEnd
event from the
Router
service to know when to update focus.
The following example shows how to find and focus the main content header in the DOM after navigation.
router.events.pipe(filter(e => e instanceofNavigationEnd)).subscribe(()=>{const mainHeader = document.querySelector('#main-content-header')if(mainHeader){
mainHeader.focus();}});
In a real application, the element that receives focus depends on your specific application structure and layout.
The focused element should put users in a position to immediately move into the main content that has just been routed into view.
You should avoid situations where focus returns to the
body
element after a route change.
Active links identification
link
CSS classes applied to active
RouterLink
elements, such as
RouterLinkActive
, provide a visual cue to identify the active link.
Unfortunately, a visual cue doesn't help blind or visually impaired users.
Applying the
aria-current
attribute to the element can help identify the active link.
For more information, see Mozilla Developer Network (MDN) aria-current).
The
RouterLinkActive
directive provides the
ariaCurrentWhenActive
input which sets the
aria-current
to a specified value when the link becomes active.
The following example shows how to apply the
active-page
class to active links as well as setting their
aria-current
attribute to
"page"
when they are active:
<nav><arouterLink="home"routerLinkActive="active-page"ariaCurrentWhenActive="page">
Home
</a><arouterLink="about"routerLinkActive="active-page"ariaCurrentWhenActive="page">
About
</a><arouterLink="shop"routerLinkActive="active-page"ariaCurrentWhenActive="page">
Shop
</a></nav>
More information
link
Accessibility - Google Web Fundamentals
ARIA specification and authoring practices
Material Design - Accessibility
Smashing Magazine
Inclusive Components
Accessibility Resources and Code Examples
W3C - Web Accessibility Initiative
Rob Dodson A11ycasts
Angular ESLint provides linting rules that can help you make sure your code meets accessibility standards.
Books
"A Web for Everyone: Designing Accessible User Experiences," Sarah Horton and Whitney Quesenbery
Immediately invoked function expression (IIFE) → none
Angular modules →
NgModules
Controller registration → component decorator
Controller function → component class
Dependency injection → dependency injection
Style sheets
Link
tag →
styles
configuration or
styleUrls
Angular
is the name for the Angular of today and tomorrow.
AngularJS
is the name for all v1.x versions of Angular.
This guide helps you transition from AngularJS to Angular
by mapping AngularJS syntax to the corresponding Angular syntax.
See the Angular syntax in this
live example
/ download example
.
Template basics
link
Templates are the user-facing part of an Angular application and are written in HTML.
The following table lists some of the key AngularJS template features with their corresponding Angular template syntax.
Bindings / interpolation → bindings / interpolation
link
AngularJS
Angular
Bindings/interpolation
Your favorite hero is: {{vm.favoriteHero}}
In AngularJS, an expression in curly braces denotes one-way binding. This binds the value of the element to a property in the controller associated with this template.
When using the
controller as
syntax, the binding is prefixed with the controller alias
vm
or
$ctrl
because you have to be specific about the source.
Bindings/interpolation
Your favorite hero is:{{favoriteHero}}
In Angular, a template expression in curly braces still denotes one-way binding. This binds the value of the element to a property of the component. The context of the binding is implied and is always the associated component, so it needs no reference variable.
For more information, see the Interpolation guide.
Filters → pipes
link
AngularJS
Angular
Filters
<td>
{{movie.title | uppercase}}
</td>
To filter output in AngularJS templates, use the pipe
|
character and one or more filters.
This example filters the
title
property to uppercase.
Pipes
<td>{{movie.title | uppercase}}</td>
In Angular you use similar syntax with the pipe
|
character to filter output, but now you call them
pipes
. Many, but not all, of the built-in filters from AngularJS are built-in pipes in Angular.
For more information, see Filters/pipes.
Local variables → input variables
link
AngularJS
Angular
Local variables
<trng-repeat="movie in vm.movies"><td>
{{movie.title}}
</td></tr>
Here,
movie
is a user-defined local variable.
Input variables
<tr *ngFor="let movie of movies"><td>{{movie.title}}</td></tr>
Angular has true template input variables that are explicitly defined using the
let
keyword.
For more information, see the Structural directive shorthand section of Structural Directives.
Template directives
link
AngularJS provides more than seventy built-in directives for templates.
Many of them are not needed in Angular because of its more capable and expressive binding system.
The following are some of the key AngularJS built-in directives and their equivalents in Angular.
ng-app
→ bootstrapping
link
AngularJS
Angular
ng-app
<bodyng-app="movieHunter">
The application startup process is called
bootstrapping
.
Although you can bootstrap an AngularJS application in code, many applications bootstrap declaratively with the
ng-app
directive, giving it the name of the module (
movieHunter
) of the application.
Bootstrapping
main.ts
import{platformBrowserDynamic} from '@angular/platform-browser-dynamic';import{AppModule} from './app/app.module';platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err));
Angular does not have a bootstrap directive. To launch the application in code, explicitly bootstrap the root module (
AppModule
) of the application in
main.ts
and the root component (
AppComponent
) of the application in
app.module.ts
.
In AngularJS, the
ng-class
directive includes/excludes CSS classes based on an expression. The expression is often a key-value object, with key defined as a CSS class name, and value as a template expression that evaluates to a Boolean.
In the first example, the
active
class is applied to the element if
isActive
is true.
You can specify multiple classes, as shown in the second example.
In Angular, the
ngClass
directive works similarly. It includes/excludes CSS classes based on an expression.
In the first example, the
active
class is applied to the element if
isActive
is true.
You can specify multiple classes, as shown in the second example.
Angular also has
class binding
, which is a good way to add or remove a single class, as shown in the third example.
For more information see Attribute, class, and style bindings page.
In AngularJS, the
ng-click
directive allows you to specify custom behavior when an element is clicked.
In the first example, when the user clicks the button, the
toggleImage()
method in the controller referenced by the
vm
controller as
alias is executed.
The second example demonstrates passing in the
$event
object, which provides details about the event to the controller.
AngularJS event-based directives do not exist in Angular. Rather, define one-way binding from the template view to the component using
event binding
.
For event binding, define the name of the target event within parenthesis and specify a template statement, in quotes, to the right of the equals. Angular then sets up an event handler for the target event. When the event is raised, the handler executes the template statement.
In the first example, when a user clicks the button, the
toggleImage()
method in the associated component is executed.
The second example demonstrates passing in the
$event
object, which provides details about the event to the component.
For a list of DOM events, see Event reference.
For more information, see the Event binding page.
ng-controller
→ component decorator
link
AngularJS
Angular
ng-controller
<divng-controller="MovieListCtrl as vm">
In AngularJS, the
ng-controller
directive attaches a controller to the view. Using the
ng-controller
, or defining the controller as part of the routing, ties the view to the controller code associated with that view.
In Angular, the template no longer specifies its associated controller. Rather, the component specifies its associated template as part of the component class decorator.
For more information, see Architecture Overview.
ng-hide
→ Bind to the
hidden
property
link
AngularJS
Angular
ng-hide
In AngularJS, the
ng-hide
directive shows or hides the associated HTML element based on an expression. For more information, see ng-show.
Bind to the
hidden
property
In Angular, you use property binding. Angular does not have a built-in
hide
directive. For more information, see ng-show.
The
ng-href
directive allows AngularJS to preprocess the
href
property.
ng-href
can replace the binding expression with the appropriate URL before the browser fetches from that URL.
In AngularJS, the
ng-href
is often used to activate a route as part of navigation.
<ang-href="#{{ moviesHash }}">
Movies
</a>
Routing is handled differently in Angular.
Bind to the
href
property
<a [href]="angularDocsUrl">Angular Docs</a>
Angular uses property binding. Angular does not have a built-in
href
directive. Place the
href
property of the element in square brackets and set it to a quoted template expression. For more information see the Property binding page. In Angular,
href
is no longer used for routing. Routing uses
routerLink
, as shown in the following example.
<a [routerLink]="['/movies']">Movies</a>
For more information on routing, see Defining a basic route in the Routing & Navigation page.
ng-if
→
*ngIf
link
AngularJS
Angular
ng-if
<tableng-if="movies.length">
In AngularJS, the
ng-if
directive removes or recreates a section of the DOM, based on an expression. If the expression is false, the element is removed from the DOM.
In this example, the
<table>
element is removed from the DOM unless the
movies
array has a length greater than zero.
*ngIf
<table *ngIf="movies.length">
The
*ngIf
directive in Angular works the same as the
ng-if
directive in AngularJS. It removes or recreates a section of the DOM based on an expression.
In this example, the
<table>
element is removed from the DOM unless the
movies
array has a length.
The (
*
) before
ngIf
is required in this example. For more information, see Structural Directives.
ng-model
→
ngModel
link
AngularJS
Angular
ng-model
<inputng-model="vm.favoriteHero"/>
In AngularJS, the
ng-model
directive binds a form control to a property in the controller associated with the template. This provides
two-way binding
whereby changes result in the value in the view and the model being synchronized.
ngModel
<input [(ngModel)]="favoriteHero"/>
In Angular,
two-way binding
is indicatedr5t by
[()]
, descriptively referred to as a "banana in a box." This syntax is a shortcut for defining both:
property binding, from the component to the view
event binding, from the view to the component
thereby providing two-way binding.
For more information on two-way binding with
ngModel
, see the Displaying and updating properties with
ngModel
section of Built-in directives.
ng-repeat
→
*ngFor
link
AngularJS
Angular
ng-repeat
<trng-repeat="movie in vm.movies">
In AngularJS, the
ng-repeat
directive repeats the associated DOM element for each item in the specified collection.
In this example, the table row (
<tr>
) element repeats for each movie object in the collection of movies.
*ngFor
<tr *ngFor="let movie of movies">
The
*ngFor
directive in Angular is like the
ng-repeat
directive in AngularJS. It repeats the associated DOM element for each item in the specified collection. More accurately, it turns the defined element (
<tr>
in this example) and its contents into a template and uses that template to instantiate a view for each item in the list.
Notice the other syntax differences:
The (
*
) before
ngFor
is required
The
let
keyword identifies
movie
as an input variable
The list preposition is
of
, not
in
For more information, see Structural Directives.
ng-show
→ Bind to the
hidden
property
link
AngularJS
Angular
ng-show
<h3ng-show="vm.favoriteHero">
Your favorite hero is: {{vm.favoriteHero}}
</h3>
In AngularJS, the
ng-show
directive shows or hides the associated DOM element, based on an expression.
In this example, the
<div>
element is shown if the
favoriteHero
variable is truthy.
Bind to the
hidden
property
<h3 [hidden]="!favoriteHero">
Your favorite hero is: {{favoriteHero}}
</h3>
Angular uses property binding. Angular has no built-in
show
directive. For hiding and showing elements, bind to the HTML
hidden
property.
To conditionally display an element the
hidden
property of the element can be used. Place the
hidden
property in square brackets and set it to a quoted template expression that evaluates to the
opposite
of
show
.
In this example, the
<div>
element is hidden if the
favoriteHero
variable is not truthy.
For more information on property binding, see the Property binding page.
ng-src
→ Bind to the
src
property
link
AngularJS
Angular
ng-src
<imgng-src="{{movie.imageurl}}">
The
ng-src
directive allows AngularJS to preprocess the
src
property. This replaces the binding expression with the appropriate URL before the browser fetches from that URL.
Bind to the
src
property
<img [src]="movie.imageurl" [alt]="movie.title">
Angular uses property binding. Angular has no built-in
src
directive. Place the
src
property in square brackets and set it to a quoted template expression.
For more information on property binding, see the Property binding page.
ng-style
→
ngStyle
link
AngularJS
Angular
ng-style
<divng-style="{color: colorPreference}">
In AngularJS, the
ng-style
directive sets a CSS style on an HTML element based on an expression. That expression is often a key-value control object with:
each key of the object defined as a CSS property
each value defined as an expression that evaluates to a value appropriate for the style
In the example, the
color
style is set to the current value of the
colorPreference
variable.
In Angular, the
ngStyle
directive works similarly. It sets a CSS style on an HTML element based on an expression.
In the first example, the
color
style is set to the current value of the
colorPreference
variable.
Angular also has
style binding
, which is good way to set a single style. This is shown in the second example.
For more information on style binding, see the Style binding section of the Attribute binding page.
For more information on the
ngStyle
directive, see the NgStyle section of the Built-in directives page.
ng-switch
→
ngSwitch
link
AngularJS
Angular
ng-switch
<divng-switch="vm.favoriteHero && vm.checkMovieHero(vm.favoriteHero)"><divng-switch-when="true">
Excellent choice.
</div><divng-switch-when="false">
No movie, sorry.
</div><divng-switch-default>
Please enter your favorite hero.
</div></div>
In AngularJS, the
ng-switch
directive swaps the contents of an element by selecting one of the templates based on the current value of an expression.
In this example, if
favoriteHero
is not set, the template displays "Please enter …" If
favoriteHero
is set, it checks the movie hero by calling a controller method. If that method returns
true
, the template displays "Excellent choice!" If that methods returns
false
, the template displays "No movie, sorry!"
ngSwitch
<span [ngSwitch]="favoriteHero &&
checkMovieHero(favoriteHero)"><p *ngSwitchCase="true">
Excellent choice!
</p><p *ngSwitchCase="false">
No movie, sorry!
</p><p *ngSwitchDefault>
Please enter your favorite hero.
</p></span>
In Angular, the
ngSwitch
directive works similarly. It displays an element whose
*ngSwitchCase
matches the current
ngSwitch
expression value.
In this example, if
favoriteHero
is not set, the
ngSwitch
value is
null
and
*ngSwitchDefault
displays, "Please enter your favorite hero." If
favoriteHero
is set, the application checks the movie hero by calling a component method. If that method returns
true
, the application selects
*ngSwitchCase="true"
and displays: "Excellent choice." If that methods returns
false
, the application selects
*ngSwitchCase="false"
and displays: "No movie, sorry."
The (
*
) before
ngSwitchCase
and
ngSwitchDefault
is required in this example.
For more information, see The NgSwitch directives section of the Built-in directives page.
Filters / pipes
link
Angular
pipes
provide formatting and transformation for data in the template, like AngularJS
filters
.
Many of the built-in filters in AngularJS have corresponding pipes in Angular.
For more information on pipes, see Pipes.
currency
→
currency
link
AngularJS
Angular
currency
<td>
{{movie.price | currency}}
</td>
Formats a number as currency.
currency
<td>{{movie.price | currency:'USD':true}}</td>
The Angular
currency
pipe is similar although some of the parameters have changed.
date
→
date
link
AngularJS
Angular
date
<td>
{{movie.releaseDate | date}}
</td>
Formats a date to a string based on the requested format.
date
<td>{{movie.releaseDate | date}}</td>
The Angular
date
pipe is similar.
filter
→ none
link
AngularJS
Angular
filter
<trng-repeat="movie in movieList | filter: {title:listFilter}">
Selects a subset of items from the defined collection, based on the filter criteria.
none
For performance reasons, no comparable pipe exists in Angular. Do all your filtering in the component. If you need the same filtering code in several templates, consider building a custom pipe.
json
→
json
link
AngularJS
Angular
json
<pre>
{{movie | json}}
</pre>
Converts a JavaScript object into a JSON string. This is useful for debugging.
json
<pre>{{movie | json}}</pre>
The Angular
json
pipe does the same thing.
limitTo
→
slice
link
AngularJS
Angular
limitTo
<trng-repeat="movie in movieList | limitTo:2:0">
Selects up to the first parameter
2
number of items from the collection starting optionally at the beginning index
0
.
slice
<tr *ngFor="let movie of movies | slice:0:2">
The
SlicePipe
does the same thing but the
order of the parameters is reversed
, in keeping with the JavaScript
Slice
method. The first parameter is the starting index and the second is the limit. As in AngularJS, coding this operation within the component instead could improve performance.
The Angular
number
pipe is similar. It provides more capabilities when defining the decimal places, as shown in the preceding second example.
Angular also has a
percent
pipe, which formats a number as a local percentage as shown in the third example.
orderBy
→ none
link
AngularJS
Angular
orderBy
<trng-repeat="movie in movieList | orderBy : 'title'">
Displays the collection in the order specified by the expression. In this example, the movie title orders the
movieList
.
none
For performance reasons, no comparable pipe exists in Angular. Instead, use component code to order or sort results. If you need the same ordering or sorting code in several templates, consider building a custom pipe.
Modules / controllers / components
link
In both AngularJS and Angular, modules help you organize your application into cohesive blocks of features.
In AngularJS, you write the code that provides the model and the methods for the view in a
controller
.
In Angular, you build a
component
.
Because much AngularJS code is in JavaScript, JavaScript code is shown in the AngularJS column.
The Angular code is shown using TypeScript.
Immediately invoked function expression (IIFE) → none
link
AngularJS
Angular
IIFE
(function(){…}());
In AngularJS, an IIFE around controller code keeps it out of the global namespace.
none
This is a nonissue in Angular because ES 2015 modules handle the namespace for you.
For more information on modules, see the Modules section of the Architecture Overview.
Angular modules →
NgModules
link
AngularJS
Angular
Angular modules
angular .module("movieHunter",["ngRoute"]);
In AngularJS, an Angular module keeps track of controllers, services, and other code. The second argument defines the list of other modules that this module depends upon.
AngularJS has code in each controller that looks up an appropriate Angular module and registers the controller with that module.
The first argument is the controller name. The second argument defines the string names of all dependencies injected into this controller, and a reference to the controller function.
Angular adds a decorator to the component class to provide any required metadata. The
@Component
decorator declares that the class is a component and provides metadata about that component such as its selector, or tag, and its template.
This is how you associate a template with logic, which is defined in the component class.
For more information, see the Components section of the Architecture Overview page.
Controller function → component class
link
AngularJS
Angular
Controller function
functionMovieListCtrl(movieService){}
In AngularJS, you write the code for the model and methods in a controller function.
Component class
exportclassMovieListComponent{}
In Angular, you create a component class to contain the data model and control methods. Use the TypeScript
export
keyword to export the class so that the component can be imported into NgModules.
For more information, see the Components section of the Architecture Overview page.
In AngularJS, you pass in any dependencies as controller function arguments. This example injects a
MovieService
.
To guard against minification problems, tell Angular explicitly that it should inject an instance of the
MovieService
in the first parameter.
Dependency injection
constructor(movieService:MovieService){}
In Angular, you pass in dependencies as arguments to the component class constructor. This example injects a
MovieService
. The TypeScript type of the first parameter tells Angular what to inject, even after minification.
For more information, see the Dependency injection section of the Architecture Overview.
Style sheets
link
Style sheets give your application a nice look.
In AngularJS, you specify the style sheets for your entire application.
As the application grows over time, the styles for the many parts of the application merge, which can cause unexpected results.
In Angular, you can still define style sheets for your entire application.
Now you can also encapsulate a style sheet within a specific component.
Link
tag →
styles
configuration or
styleUrls
link
AngularJS
Angular
Link
tag
<linkhref="styles.css"rel="stylesheet"/>
AngularJS, uses a
link
tag in the head section of the
index.html
file to define the styles for the application.
styles
configuration
"styles":["styles.css"],
With the Angular CLI, you can configure your global styles in the
angular.json
file. You can rename the extension to
.scss
to use sass.
styleUrls
In Angular, you can use the
styles
or
styleUrls
property of the
@Component
metadata to define a style sheet for a particular component.
styleUrls:['./movie-list.component.css'],
This allows you to set appropriate styles for individual components that do not leak into other parts of the application.
When you use ahead-of-time compilation (AOT), you can control how your application is compiled by specifying
template
compiler options in the TypeScript configuration file.
The template options object,
angularCompilerOptions
, is a sibling to the
compilerOptions
object that supplies standard options to the TypeScript compiler.
Like the TypeScript compiler, the Angular AOT compiler also supports
extends
in the
angularCompilerOptions
section of the TypeScript configuration file.
The
extends
property is at the top level, parallel to
compilerOptions
and
angularCompilerOptions
.
A TypeScript configuration can inherit settings from another file using the
extends
property.
The configuration options from the base file are loaded first, then overridden by those in the inheriting configuration file.
For more information, see the TypeScript Handbook.
Template options
link
The following options are available for configuring the AOT template compiler.
allowEmptyCodegenFiles
link
When
true
, create all possible files even if they are empty.
Default is
false
.
Used by the Bazel build rules to simplify how Bazel rules track file dependencies.
Do not use this option outside of the Bazel rules.
annotationsAs
link
Modifies how Angular-specific annotations are emitted to improve tree-shaking.
Non-Angular annotations are not affected.
One of
static fields
or
decorators
. The default value is
static fields
.
By default, the compiler replaces decorators with a static field in the class, which allows advanced tree-shakers like Closure compiler to remove unused classes
The
decorators
value leaves the decorators in place, which makes compilation faster.
TypeScript emits calls to the
__decorate
helper.
Use
--emitDecoratorMetadata
for runtime reflection.
NOTE
:
That the resulting code cannot tree-shake properly.
annotateForClosureCompiler
link
When
true
, use Tsickle to annotate the emitted JavaScript with JSDoc comments needed by the Closure Compiler.
Default is
false
.
compilationMode
link
Specifies the compilation mode to use.
The following modes are available:
Modes
Details
'full'
Generates fully AOT-compiled code according to the version of Angular that is currently being used.
'partial'
Generates code in a stable, but intermediate form suitable for a published library.
The default value is
'full'
.
disableExpressionLowering
link
When
true
, the default, transforms code that is or could be used in an annotation, to allow it to be imported from template factory modules.
See metadata rewriting for more information.
When
false
, disables this rewriting, requiring the rewriting to be done manually.
disableTypeScriptVersionCheck
link
When
true
, the compiler does not look at the TypeScript version and does not report an error when an unsupported version of TypeScript is used.
Not recommended, as unsupported versions of TypeScript might have undefined behavior.
Default is
false
.
enableI18nLegacyMessageIdFormat
link
Instructs the Angular template compiler to create legacy ids for messages that are tagged in templates by the
i18n
attribute.
See Mark text for translations for more information about marking messages for localization.
Set this option to
false
unless your project relies upon translations that were created earlier using legacy IDs.
Default is
true
.
The pre-Ivy message extraction tooling created a variety of legacy formats for extracted message IDs.
These message formats have some issues, such as whitespace handling and reliance upon information inside the original HTML of a template.
The new message format is more resilient to whitespace changes, is the same across all translation file formats, and can be created directly from calls to
$localize
.
This allows
$localize
messages in application code to use the same ID as identical
i18n
messages in component templates.
enableResourceInlining
link
When
true
, replaces the
templateUrl
and
styleUrls
properties in all
@Component
decorators with inline content in the
template
and
styles
properties.
When enabled, the
.js
output of
ngc
does not include any lazy-loaded template or style URLs.
For library projects created with the Angular CLI, the development configuration default is
true
.
enableLegacyTemplate
link
When
true
, enables the deprecated
<template>
element in place of
<ng-template>
.
Default is
false
.
Might be required by some third-party Angular libraries.
flatModuleId
link
The module ID to use for importing a flat module (when
flatModuleOutFile
is
true
).
References created by the template compiler use this module name when importing symbols from the flat module.
Ignored if
flatModuleOutFile
is
false
.
flatModuleOutFile
link
When
true
, generates a flat module index of the given filename and the corresponding flat module metadata.
Use to create flat modules that are packaged similarly to
@angular/core
and
@angular/common
.
When this option is used, the
package.json
for the library should refer to the created flat module index instead of the library index file.
Produces only one
.metadata.json
file, which contains all the metadata necessary for symbols exported from the library index.
In the created
.ngfactory.js
files, the flat module index is used to import symbols. Symbols that include both the public API from the library index as well as shrouded internal symbols.
By default the
.ts
file supplied in the
files
field is assumed to be the library index.
If more than one
.ts
file is specified,
libraryIndex
is used to select the file to use.
If more than one
.ts
file is supplied without a
libraryIndex
, an error is produced.
A flat module index
.d.ts
and
.js
is created with the given
flatModuleOutFile
name in the same location as the library index
.d.ts
file.
For example, if a library uses the
public_api.ts
file as the library index of the module, the
tsconfig.json
files
field would be
["public_api.ts"]
.
The
flatModuleOutFile
option could then be set, for example, to
"index.js"
, which produces
index.d.ts
and
index.metadata.json
files.
The
module
field of the library's
package.json
would be
"index.js"
and the
typings
field would be
"index.d.ts"
.
fullTemplateTypeCheck
link
When
true
, the recommended value, enables the binding expression validation phase of the template compiler. This phase uses TypeScript to verify binding expressions.
For more information, see Template type checking.
Default is
false
, but when you use the Angular CLI command
ng new --strict
, it is set to
true
in the new project's configuration.
The
fullTemplateTypeCheck
option has been deprecated in Angular 13 in favor of the
strictTemplates
family of compiler options.
generateCodeForLibraries
link
When
true
, creates factory files (
.ngfactory.js
and
.ngstyle.js
) for
.d.ts
files with a corresponding
.metadata.json
file. The default value is
true
.
When
false
, factory files are created only for
.ts
files.
Do this when using factory summaries.
preserveWhitespaces
link
When
false
, the default, removes blank text nodes from compiled templates, which results in smaller emitted template factory modules.
Set to
true
to preserve blank text nodes.
skipMetadataEmit
link
When
true
, does not produce
.metadata.json
files.
Default is
false
.
The
.metadata.json
files contain information needed by the template compiler from a
.ts
file that is not included in the
.d.ts
file produced by the TypeScript compiler.
This information includes, for example, the content of annotations, such as a component's template, which TypeScript emits to the
.js
file but not to the
.d.ts
file.
You can set to
true
when using factory summaries, because the factory summaries include a copy of the information that is in the
.metadata.json
file.
Set to
true
if you are using TypeScript's
--outFile
option, because the metadata files are not valid for this style of TypeScript output.
The Angular community does not recommend using
--outFile
with Angular.
Use a bundler, such as webpack, instead.
skipTemplateCodegen
link
When
true
, does not emit
.ngfactory.js
and
.ngstyle.js
files.
This turns off most of the template compiler and disables the reporting of template diagnostics.
Can be used to instruct the template compiler to produce
.metadata.json
files for distribution with an
npm
package. This avoids the production of
.ngfactory.js
and
.ngstyle.js
files that cannot be distributed to
npm
.
For library projects created with the Angular CLI, the development configuration default is
true
.
strictMetadataEmit
link
When
true
, reports an error to the
.metadata.json
file if
"skipMetadataEmit"
is
false
.
Default is
false
.
Use only when
"skipMetadataEmit"
is
false
and
"skipTemplateCodegen"
is
true
.
This option is intended to verify the
.metadata.json
files emitted for bundling with an
npm
package.
The validation is strict and can emit errors for metadata that would never produce an error when used by the template compiler.
You can choose to suppress the error emitted by this option for an exported symbol by including
@dynamic
in the comment documenting the symbol.
It is valid for
.metadata.json
files to contain errors.
The template compiler reports these errors if the metadata is used to determine the contents of an annotation.
The metadata collector cannot predict the symbols that are designed for use in an annotation. It preemptively includes error nodes in the metadata for the exported symbols.
The template compiler can then use the error nodes to report an error if these symbols are used.
If the client of a library intends to use a symbol in an annotation, the template compiler does not normally report this. It gets reported after the client actually uses the symbol.
This option allows detection of these errors during the build phase of the library and is used, for example, in producing Angular libraries themselves.
For library projects created with the Angular CLI, the development configuration default is
true
.
strictInjectionParameters
link
When
true
, reports an error for a supplied parameter whose injection type cannot be determined.
When
false
, constructor parameters of classes marked with
@Injectable
whose type cannot be resolved produce a warning.
The recommended value is
true
, but the default value is
false
.
When you use the Angular CLI command
ng new --strict
, it is set to
true
in the created project's configuration.
strictTemplates
link
When
true
, enables strict template type checking.
The strictness flags that this open enables allow you to turn on and off specific types of strict template type checking.
See troubleshooting template errors.
When you use the Angular CLI command
ng new --strict
, it is set to
true
in the new project's configuration.
trace
link
When
true
, prints extra information while compiling templates.
Default is
false
.
Command line options
link
Most of the time you interact with the Angular Compiler indirectly using Angular CLI. When debugging certain issues, you might find it useful to invoke the Angular Compiler directly.
You can use the
ngc
command provided by the
@angular/compiler-cli
npm package to call the compiler from the command line.
The
ngc
command is just a wrapper around TypeScript's
tsc
compiler command and is primarily configured via the
tsconfig.json
configuration options documented in the previous sections.
Besides the configuration file, you can also use
tsc
command line options to configure
ngc
.
This document describes the Angular Package Format (APF).
APF is an Angular specific specification for the structure and format of npm packages that is used by all first-party Angular packages (
@angular/core
,
@angular/material
, etc.) and most third-party Angular libraries.
APF enables a package to work seamlessly under most common scenarios that use Angular.
Packages that use APF are compatible with the tooling offered by the Angular team as well as wider JavaScript ecosystem.
It is recommended that third-party library developers follow the same npm package format.
APF is versioned along with the rest of Angular, and every major version improves the package format.
You can find the versions of the specification prior to v13 in this google doc.
Why specify a package format?
link
In today's JavaScript landscape, developers consume packages in many different ways, using many different toolchains (Webpack, rollup, esbuild, etc.).
These tools may understand and require different inputs - some tools may be able to process the latest ES language version, while others may benefit from directly consuming an older ES version.
The Angular distribution format supports all of the commonly used development tools and workflows, and adds emphasis on optimizations that result either in smaller application payload size or faster development iteration cycle (build time).
Developers can rely on Angular CLI and ng-packagr (a build tool Angular CLI uses) to produce packages in the Angular package format.
See the Creating Libraries guide for more details.
File layout
link
The following example shows a simplified version of the
@angular/core
package's file layout, with an explanation for each file in the package.
node_modules/@angular/core
README.md
package.json
index.d.ts
esm2020
core.mjs
index.mjs
public_api.mjs
testing
fesm2015
core.mjs
core.mjs.map
testing.mjs
testing.mjs.map
fesm2020
core.mjs
core.mjs.map
testing.mjs
testing.mjs.map
testing
index.d.ts
This table describes the file layout under
node_modules/@angular/core
annotated to describe the purpose of files and directories:
Files
Purpose
README.md
Package README, used by npmjs web UI.
package.json
Primary
package.json
, describing the package itself as well as all available entrypoints and code formats. This file contains the "exports" mapping used by runtimes and tools to perform module resolution.
index.d.ts
Bundled
.d.ts
for the primary entrypoint
@angular/core
.
esm2020/
─
core.mjs
─
index.mjs
─
public_api.mjs
Tree of
@angular/core
sources in unflattened ES2020 format.
esm2020/testing/
Tree of the
@angular/core/testing
entrypoint in unflattened ES2020 format.
Code for all entrypoints in flattened (FESM) ES2020 format, along with source maps.
testing/
Directory representing the "testing" entrypoint.
testing/index.d.ts
Bundled
.d.ts
for the
@angular/core/testing
entrypoint.
package.json
link
The primary
package.json
contains important package metadata, including the following:
It declares the package to be in EcmaScript Module (ESM) format
It contains an
"exports"
field which defines the available source code formats of all entrypoints
It contains keys which define the available source code formats of the primary
@angular/core
entrypoint, for tools which do not understand
"exports"
.
These keys are considered deprecated, and could be removed as the support for
"exports"
rolls out across the ecosystem.
It declares whether the package contains side effects
ESM declaration
link
The top-level
package.json
contains the key:
{"type":"module"}
This informs resolvers that code within the package is using EcmaScript Modules as opposed to CommonJS modules.
Of primary interest are the
"."
and the
"./testing"
keys, which define the available code formats for the
@angular/core
primary entrypoint and the
@angular/core/testing
secondary entrypoint, respectively.
For each entrypoint, the available formats are:
Formats
Details
Typings (
.d.ts
files)
.d.ts
files are used by TypeScript when depending on a given package.
es2020
ES2020 code flattened into a single source file.
es2015
ES2015 code flattened into a single source file.
esm2020
ES2020 code in unflattened source files (this format is included for experimentation - see this discussion of defaults for details).
Tooling that is aware of these keys may preferentially select a desirable code format from
"exports"
.
The remaining 2 keys control the default behavior of tooling:
"node"
selects flattened ES2015 code when the package is loaded in Node.
This format is used due to the requirements of
zone.js
, which does not support native
async
/
await
ES2017 syntax.
Therefore, Node is instructed to use ES2015 code, where
async
/
await
structures have been downleveled into Promises.
"default"
selects flattened ES2020 code for all other consumers.
Libraries may want to expose additional static files which are not captured by the exports of the JavaScript-based entry-points such as Sass mixins or pre-compiled CSS.
For more information, see Managing assets in a library.
Legacy resolution keys
link
In addition to
"exports"
, the top-level
package.json
also defines legacy module resolution keys for resolvers that don't support
"exports"
.
For
@angular/core
these are:
As shown in the preceding code snippet, a module resolver can use these keys to load a specific code format.
NOTE
:
Instead of
"default"
,
"module"
selects the format both for Node as well as any tooling not configured to use a specific key.
As with
"node"
, ES2015 code is selected due to the constraints of ZoneJS.
Side effects
link
The last function of
package.json
is to declare whether the package has side effects.
{"sideEffects":false}
Most Angular packages should not depend on top-level side effects, and thus should include this declaration.
Entrypoints and code splitting
link
Packages in the Angular Package Format contain one primary entrypoint and zero or more secondary entrypoints (for example,
@angular/common/http
).
Entrypoints serve several functions.
They define the module specifiers from which users import code (for example,
@angular/core
and
@angular/core/testing
).
Users typically perceive these entrypoints as distinct groups of symbols, with different purposes or capability.
Specific entrypoints might only be used for special purposes, such as testing.
Such APIs can be separated out from the primary entrypoint to reduce the chance of them being used accidentally or incorrectly.
They define the granularity at which code can be lazily loaded.
Many modern build tools are only capable of "code splitting" (aka lazy loading) at the ES Module level.
The Angular Package Format uses primarily a single "flat" ES Module per entry point. This means that most build tooling is not able to split code with a single entry point into multiple output chunks.
The general rule for APF packages is to use entrypoints for the smallest sets of logically connected code possible.
For example, the Angular Material package publishes each logical component or set of components as a separate entrypoint - one for Button, one for Tabs, etc.
This allows each Material component to be lazily loaded separately, if desired.
Not all libraries require such granularity.
Most libraries with a single logical purpose should be published as a single entrypoint.
@angular/core
for example uses a single entrypoint for the runtime, because the Angular runtime is generally used as a single entity.
Resolution of secondary entry points
link
Secondary entrypoints can be resolved via the
"exports"
field of the
package.json
for the package.
README.md
link
The README file in the Markdown format that is used to display description of a package on npm and GitHub.
Example README content of @angular/core package:
Angular
=======
The sources for this package are in the main [Angular](https://github.com/angular/angular) repo.Please file issues and pull requests against that repo.
License: MIT
Partial compilation
link
Libraries in the Angular Package Format must be published in "partial compilation" mode.
This is a compilation mode for
ngc
which produces compiled Angular code that is not tied to a specific Angular runtime version, in contrast to the full compilation used for applications, where the Angular compiler and runtime versions must match exactly.
To partially compile Angular code, use the
compilationMode
flag in the
angularCompilerOptions
property of your
tsconfig.json
:
Partially compiled library code is then converted to fully compiled code during the application build process by the Angular CLI.
If your build pipeline does not use the Angular CLI then refer to the Consuming partial ivy code outside the Angular CLI guide.
Optimizations
link
Flattening of ES modules
link
The Angular Package Format specifies that code be published in "flattened" ES module format.
This significantly reduces the build time of Angular applications as well as download and parse time of the final application bundle.
Please check out the excellent post "The cost of small modules" by Nolan Lawson.
The Angular compiler can generate index ES module files. Tools like Rollup can use these files to generate flattened modules in a
Flattened ES Module
(FESM) file format.
FESM is a file format created by flattening all ES Modules accessible from an entrypoint into a single ES Module.
It's formed by following all imports from a package and copying that code into a single file while preserving all public ES exports and removing all private imports.
The abbreviated name, FESM, pronounced
phe-som
, can be followed by a number such as FESM5 or FESM2015.
The number refers to the language level of the JavaScript inside the module.
Accordingly a FESM5 file would be ESM+ES5 and include import/export statements and ES5 source code.
To generate a flattened ES Module index file, use the following configuration options in your tsconfig.json file:
Once the index file (for example,
my-ui-lib.js
) is generated by ngc, bundlers and optimizers like Rollup can be used to produce the flattened ESM file.
Note about the defaults in package.json
link
As of webpack v4, the flattening of ES modules optimization should not be necessary for webpack users. It should be possible to get better code-splitting without flattening of modules in webpack.
In practice, size regressions can still be seen when using unflattened modules as input for webpack v4.
This is why
module
and
es2020
package.json entries still point to FESM files.
This issue is being investigated. It is expected to switch the
module
and
es2020
package.json entry points to unflattened files after the size regression issue is resolved.
The APF currently includes unflattened ESM2020 code for the purpose of validating such a future change.
"sideEffects" flag
link
By default, EcmaScript Modules are side-effectful: importing from a module ensures that any code at the top level of that module should run.
This is often undesirable, as most side-effectful code in typical modules is not truly side-effectful, but instead only affects specific symbols.
If those symbols are not imported and used, it's often desirable to remove them in an optimization process known as tree-shaking, and the side-effectful code can prevent this.
Build tools such as Webpack support a flag which allows packages to declare that they do not depend on side-effectful code at the top level of their modules, giving the tools more freedom to tree-shake code from the package.
The end result of these optimizations should be smaller bundle size and better code distribution in bundle chunks after code-splitting.
This optimization can break your code if it contains non-local side-effects - this is however not common in Angular applications and it's usually a sign of bad design.
The recommendation is for all packages to claim the side-effect free status by setting the
sideEffects
property to
false
, and that developers follow the Angular Style Guide which naturally results in code without non-local side-effects.
More info: webpack docs on side effects
ES2020 language level
link
ES2020 Language level is now the default language level that is consumed by Angular CLI and other tooling.
The Angular CLI down-levels the bundle to a language level that is supported by all targeted browsers at application build time.
d.ts bundling / type definition flattening
link
As of APF v8 it is now preferred to run API Extractor, to bundle TypeScript definitions so that the entire API appears in a single file.
In prior APF versions each entry point would have a
src
directory next to the .d.ts entry point and this directory contained individual d.ts files matching the structure of the original source code.
While this distribution format is still allowed and supported, it is highly discouraged because it confuses tools like IDEs that then offer incorrect autocompletion, and allows users to depend on deep-import paths which are typically not considered to be public API of a library or a package.
Tslib
link
As of APF v10, it is recommended to add tslib as a direct dependency of your primary entry-point.
This is because the tslib version is tied to the TypeScript version used to compile your library.
Examples
link
@angular/core package
@angular/material package
Definition of terms
link
The following terms are used throughout this document intentionally.
In this section are the definitions of all of them to provide additional clarity.
Package
link
The smallest set of files that are published to NPM and installed together, for example
@angular/core
.
This package includes a manifest called package.json, compiled source code, typescript definition files, source maps, metadata, etc.
The package is installed with
npm install @angular/core
.
Symbol
link
A class, function, constant, or variable contained in a module and optionally made visible to the external world via a module export.
Module
link
Short for ECMAScript Modules.
A file containing statements that import and export symbols.
This is identical to the definition of modules in the ECMAScript spec.
ESM
link
Short for ECMAScript Modules (see above).
FESM
link
Short for Flattened ES Modules and consists of a file format created by flattening all ES Modules accessible from an entry point into a single ES Module.
Module ID
link
The identifier of a module used in the import statements (for example,
@angular/core
).
The ID often maps directly to a path on the filesystem, but this is not always the case due to various module resolution strategies.
Module specifier
link
A module identifier (see above).
Module resolution strategy
link
Algorithm used to convert Module IDs to paths on the filesystem.
Node.js has one that is well specified and widely used, TypeScript supports several module resolution strategies, Closure Compiler has yet another strategy.
Module format
link
Specification of the module syntax that covers at minimum the syntax for the importing and exporting from a file.
Common module formats are CommonJS (CJS, typically used for Node.js applications) or ECMAScript Modules (ESM).
The module format indicates only the packaging of the individual modules, but not the JavaScript language features used to make up the module content.
Because of this, the Angular team often uses the language level specifier as a suffix to the module format, (for example, ESM+ES2015 specifies that the module is in ESM format and contains code down-leveled to ES2015).
Bundle
link
An artifact in the form of a single JS file, produced by a build tool (for example, Webpack or Rollup) that contains symbols originating in one or more modules.
Bundles are a browser-specific workaround that reduce network strain that would be caused if browsers were to start downloading hundreds if not tens of thousands of files.
Node.js typically doesn't use bundles.
Common bundle formats are UMD and System.register.
Language level
link
The language of the code (ES2015 or ES2020).
Independent of the module format.
Entry point
link
A module intended to be imported by the user.
It is referenced by a unique module ID and exports the public API referenced by that module ID.
An example is
@angular/core
or
@angular/core/testing
.
Both entry points exist in the
@angular/core
package, but they export different symbols.
A package can have many entry points.
Deep import
link
A process of retrieving symbols from modules that are not Entry Points.
These module IDs are usually considered to be private APIs that can change over the lifetime of the project or while the bundle for the given package is being created.
Top-Level import
link
An import coming from an entry point.
The available top-level imports are what define the public API and are exposed in "@angular/name" modules, such as
@angular/core
or
@angular/common
.
Tree-shaking
link
The process of identifying and removing code not used by an application - also known as dead code elimination.
This is a global optimization performed at the application level using tools like Rollup, Closure Compiler, or Terser.
AOT compiler
link
The Ahead of Time Compiler for Angular.
Flattened type definitions
link
The bundled TypeScript definitions generated from API Extractor.