Any developer that has used a client framework is intimately familiar with two basic operations in an application: iterative rendering from a collection and conditional rendering. The new Angular 2 implementations look a bit different but operate in much the same way.
The code, links, and a live example are available at .
Suppose you had the following application:
[app/article-list.component.ts] import {Component} from '@angular/core'; @Component({ selector: 'article-list', template: '' }) export class ArticleListComponent { articles:Array<Object> = [ {title: 'Foo', active: true}, {title: 'Bar', active: false}, {title: 'Baz', active: true} ]; }
Your objective is to iterate through this and display the article title only if it is set as active.
Similar to Angular 1, Angular 2 provides you with directives to accomplish this task. ngFor
is used to iterate through the articles
collection:
[app/article-list.component.ts] import {Component} from '@angular/core'; @Component({ selector: 'article-list', template: ` <div *ngFor="let article of articles; let i = index"> <h1> {{i}}: {{article.title}} </h1> </div> ` }) export class ArticleListComponent { articles:Array<Object> = [ { title: 'Foo', active: true }, { title: 'Bar', active: false }, { title: 'Baz', active: true } ]; }
Similar to ngFor
, ngIf
can be incorporated as follows:
[app/article-list.component.ts] import {Component} from 'angular2/core'; @Component({ selector: 'article-list', template: ` <div *ngFor="let article of articles; let i = index"> <h1 *ngIf="article.active"> {{i}}: {{ article.title }} </h1> </div> ` }) export class ArticleListComponent { articles:Array<Object> = [ {title: 'Foo', active: true}, {title: 'Bar', active: false}, {title: 'Baz', active: true} ]; }
With this, you will see that only the objects in the articles
array with active:true
are rendered.
At first, the asterisk and pound sign notation could be confusing for many developers. For most applications, you will not need to know how this syntactic sugar actually works behind the scenes.
In reality, Angular decomposes all the structural directives prefixed with * to utilize a template. First, Angular breaks down ngFor
and ngIf
to use the template directives on the same element. The syntax does not change much yet:
[app/article-list.component.ts] import {Component} from '@angular/core'; @Component({ selector: 'article-list', template: ` <div template="ngFor let article of articles; let i = index"> <h1 template="ngIf article.active"> {{i}}: {{ article.title }} </h1> </div> ` }) export class ArticleList { articles: Array<Object>, constructor() { this.articles = [ { title: 'Foo', active: true }, { title: 'Bar', active: false }, { title: 'Baz', active: true } ]; } }
Following this, Angular decomposes this template
directive into a wrapping <template>
element:
[app/article-list.component.ts] import {Component} from '@angular/core'; @Component({ selector: 'article-list', template: ` <template ngFor let-article [ngForOf]="articles" let-i="index"> <div> <template [ngIf]="article.active"> <h1> {{i}}: {{article.title}} </h1> </template> </div> </template> ` }) export class ArticleList { articles: Array<Object>, constructor() { this.articles = [ { title: 'Foo', active: true }, { title: 'Bar', active: false }, { title: 'Baz', active: true } ]; } }
Note that both the versions displayed here—either using the template
directive or the <template>
element—will behave identically to using the original structural directives. That being said, there generally will not be a reason to ever do it this way; this is merely a demonstration to show you how Angular understands these directives behind the scenes.
When inspecting the actual DOM of these examples using ngFor
and ngIf
, you will be able to see Angular's automatically added HTML comments that describe how it interprets your markup and translates it into template bindings.
The template
element is born out of the Web Components' specification. Templates are a definition of how a DOM subtree can eventually be defined as a unit, but the elements that appear within it are not created or active until the template is actually used to create an instance from that template. Not all web browsers support web components, so Angular 2 does a polyfill to emulate proper template behavior.
In this way, the ngFor
directive is actually creating a web component template that utilizes the subordinate ngForOf
binding, which is a property of NgFor
. Each instance in articles
will use the template to create a DOM section, and within this section, the article
and index
template variables will be available for interpolation.