Книга: Angular 2 Cookbook
Назад: Projecting nested content using ngContent
Дальше: Referencing elements using template variables

Using ngFor and ngIf structural directives for model-based DOM control

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.

Note

The code, links, and a live example are available at .

Getting ready

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.

How to do it...

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.

How it works...

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

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.

Tip

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.

There's more...

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.

See also

  • Using decorators to build and style a simple component describes the building blocks of implementing an Angular 2 component
  • Passing members from a parent component into a child component goes through the basics of downward data flow between components
  • Binding to native element attributes shows how Angular 2 interfaces with HTML element attributes
  • Attaching behavior to DOM elements with directives demonstrates how to attach behavior to elements with attribute directives
  • Attribute property binding shows Angular 2's clever way of deep referencing element properties
  • Utilizing component lifecycle hooks gives an example of how you can integrate with Angular 2's component rendering flow.
Назад: Projecting nested content using ngContent
Дальше: Referencing elements using template variables

thank you
Flame
cant read the code since it is all on a single line. Also this comments section is russian
Rakuneque
DATA COLLECTION AND ANALYSIS Two reviewers extracted data and assessed methodological quality independently lasix torsemide conversion Many others were in that space already