詳細ガイド
ディレクティブ

組み込みディレクティブ

ディレクティブは、Angularアプリケーションの要素に追加の動作を追加するクラスです。

Angularの組み込みディレクティブを使用して、フォームやリスト、スタイルおよびユーザーに見えるものを管理します。

Angularディレクティブの種類は以下のとおりです。

ディレクティブの種類 詳細
コンポーネント テンプレートで使用されます。このタイプのディレクティブは、最も一般的なディレクティブタイプです。
属性ディレクティブ 要素、コンポーネント、または他のディレクティブの外観や動作を変更します。
構造ディレクティブ DOM レイアウトを、DOM 要素の追加と削除によって変更します。

このガイドでは、組み込みの 属性ディレクティブ構造ディレクティブ を取り上げます。

組み込み属性ディレクティブ

属性ディレクティブは、他のHTML要素、属性、プロパティ、およびコンポーネントの動作を監視して変更します。

最も一般的な属性ディレクティブは以下のとおりです。

一般的なディレクティブ 詳細
NgClass CSS クラスのセットを追加および削除します。
NgStyle HTML スタイルのセットを追加および削除します。
NgModel HTML フォーム要素に双方向データバインディングを追加します。

HELPFUL: 組み込みディレクティブは、公開APIのみを使用します。他のディレクティブがアクセスできないプライベートAPIには、特別なアクセス権がありません。

NgClass を使用してクラスを追加および削除する

ngClass を使用して、複数のCSSクラスを同時に追加または削除します。

HELPFUL: 単一の クラスを追加または削除するには、NgClass ではなく クラスバインディング を使用します。

コンポーネントに NgClass をインポートする

NgClass を使用するには、コンポーネントの imports リストに追加します。

src/app/app.component.ts (NgClass インポート)

      
import {Component, OnInit} from '@angular/core';import {JsonPipe} from '@angular/common';import {NgIf} from '@angular/common';import {NgFor} from '@angular/common';import {NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common';import {NgStyle} from '@angular/common';import {NgClass} from '@angular/common';import {FormsModule} from '@angular/forms';import {Item} from './item';import {ItemDetailComponent} from './item-detail/item-detail.component';import {ItemSwitchComponents} from './item-switch.component';import {StoutItemComponent} from './item-switch.component';@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css'],  imports: [    NgIf, // <-- import into the component    NgFor, // <-- import into the component    NgStyle, // <-- import into the component    NgSwitch, // <-- import into the component    NgSwitchCase,    NgSwitchDefault,    NgClass, // <-- import into the component    FormsModule, // <--- import into the component    JsonPipe,    ItemDetailComponent,    ItemSwitchComponents,    StoutItemComponent,  ],})export class AppComponent implements OnInit {  canSave = true;  isSpecial = true;  isUnchanged = true;  isActive = true;  nullCustomer: string | null = null;  currentCustomer = {    name: 'Laura',  };  item!: Item; // defined to demonstrate template context precedence  items: Item[] = [];  currentItem!: Item;  // trackBy change counting  itemsNoTrackByCount = 0;  itemsWithTrackByCount = 0;  itemsWithTrackByCountReset = 0;  itemIdIncrement = 1;  currentClasses: Record<string, boolean> = {};  currentStyles: Record<string, string> = {};  ngOnInit() {    this.resetItems();    this.setCurrentClasses();    this.setCurrentStyles();    this.itemsNoTrackByCount = 0;  }  setUppercaseName(name: string) {    this.currentItem.name = name.toUpperCase();  }  setCurrentClasses() {    // CSS classes: added/removed per current state of component properties    this.currentClasses = {      saveable: this.canSave,      modified: !this.isUnchanged,      special: this.isSpecial,    };  }  setCurrentStyles() {    // CSS styles: set per current state of component properties    this.currentStyles = {      'font-style': this.canSave ? 'italic' : 'normal',      'font-weight': !this.isUnchanged ? 'bold' : 'normal',      'font-size': this.isSpecial ? '24px' : '12px',    };  }  isActiveToggle() {    this.isActive = !this.isActive;  }  giveNullCustomerValue() {    this.nullCustomer = 'Kelly';  }  resetItems() {    this.items = Item.items.map((item) => item.clone());    this.currentItem = this.items[0];    this.item = this.currentItem;  }  resetList() {    this.resetItems();    this.itemsWithTrackByCountReset = 0;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;  }  changeIds() {    this.items.forEach((i) => (i.id += 1 * this.itemIdIncrement));    this.itemsWithTrackByCountReset = -1;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;    this.itemsWithTrackByCount = ++this.itemsWithTrackByCount;  }  clearTrackByCounts() {    this.resetItems();    this.itemsNoTrackByCount = 0;    this.itemsWithTrackByCount = 0;    this.itemIdIncrement = 1;  }  trackByItems(index: number, item: Item): number {    return item.id;  }  trackById(index: number, item: any): number {    return item.id;  }  getValue(event: Event): string {    return (event.target as HTMLInputElement).value;  }}

式を使用して NgClass を使用

スタイルを設定する要素に、[ngClass] を追加して、式に等しく設定します。 この場合、isSpecial はブール値であり、app.component.tstrue に設定されています。 isSpecial がtrueのため、ngClass<div>special というクラスを適用します。

src/app/app.component.html

      
<h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

メソッドを使用して NgClass を使用

  1. メソッドを使用して NgClass を使用するには、メソッドをコンポーネントクラスに追加します。 次の例では、setCurrentClasses() は3つの他のコンポーネントプロパティの true または false 状態に基づいて、3つのクラスを追加または削除するオブジェクトを使用してcurrentClasses プロパティを設定します。

    オブジェクトの各キーは、CSSクラス名です。 キーが true の場合、ngClass はクラスを追加します。 キーが false の場合、ngClass はクラスを削除します。

    src/app/app.component.ts

          
    import {Component, OnInit} from '@angular/core';import {JsonPipe} from '@angular/common';import {NgIf} from '@angular/common';import {NgFor} from '@angular/common';import {NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common';import {NgStyle} from '@angular/common';import {NgClass} from '@angular/common';import {FormsModule} from '@angular/forms';import {Item} from './item';import {ItemDetailComponent} from './item-detail/item-detail.component';import {ItemSwitchComponents} from './item-switch.component';import {StoutItemComponent} from './item-switch.component';@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css'],  imports: [    NgIf, // <-- import into the component    NgFor, // <-- import into the component    NgStyle, // <-- import into the component    NgSwitch, // <-- import into the component    NgSwitchCase,    NgSwitchDefault,    NgClass, // <-- import into the component    FormsModule, // <--- import into the component    JsonPipe,    ItemDetailComponent,    ItemSwitchComponents,    StoutItemComponent,  ],})export class AppComponent implements OnInit {  canSave = true;  isSpecial = true;  isUnchanged = true;  isActive = true;  nullCustomer: string | null = null;  currentCustomer = {    name: 'Laura',  };  item!: Item; // defined to demonstrate template context precedence  items: Item[] = [];  currentItem!: Item;  // trackBy change counting  itemsNoTrackByCount = 0;  itemsWithTrackByCount = 0;  itemsWithTrackByCountReset = 0;  itemIdIncrement = 1;  currentClasses: Record<string, boolean> = {};  currentStyles: Record<string, string> = {};  ngOnInit() {    this.resetItems();    this.setCurrentClasses();    this.setCurrentStyles();    this.itemsNoTrackByCount = 0;  }  setUppercaseName(name: string) {    this.currentItem.name = name.toUpperCase();  }  setCurrentClasses() {    // CSS classes: added/removed per current state of component properties    this.currentClasses = {      saveable: this.canSave,      modified: !this.isUnchanged,      special: this.isSpecial,    };  }  setCurrentStyles() {    // CSS styles: set per current state of component properties    this.currentStyles = {      'font-style': this.canSave ? 'italic' : 'normal',      'font-weight': !this.isUnchanged ? 'bold' : 'normal',      'font-size': this.isSpecial ? '24px' : '12px',    };  }  isActiveToggle() {    this.isActive = !this.isActive;  }  giveNullCustomerValue() {    this.nullCustomer = 'Kelly';  }  resetItems() {    this.items = Item.items.map((item) => item.clone());    this.currentItem = this.items[0];    this.item = this.currentItem;  }  resetList() {    this.resetItems();    this.itemsWithTrackByCountReset = 0;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;  }  changeIds() {    this.items.forEach((i) => (i.id += 1 * this.itemIdIncrement));    this.itemsWithTrackByCountReset = -1;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;    this.itemsWithTrackByCount = ++this.itemsWithTrackByCount;  }  clearTrackByCounts() {    this.resetItems();    this.itemsNoTrackByCount = 0;    this.itemsWithTrackByCount = 0;    this.itemIdIncrement = 1;  }  trackByItems(index: number, item: Item): number {    return item.id;  }  trackById(index: number, item: any): number {    return item.id;  }  getValue(event: Event): string {    return (event.target as HTMLInputElement).value;  }}
  2. テンプレートで、要素のクラスを設定するために、currentClasses に対する ngClass プロパティバインディングを追加します。

    src/app/app.component.html

          
    <h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

このユースケースでは、Angularは初期化時に、および currentClasses オブジェクトの再代入によって発生した変更が発生した場合に、クラスを適用します。 完全な例では、ユーザーが Refresh currentClasses ボタンをクリックしたときに、ngOnInit() を使用して最初に setCurrentClasses() を呼び出します。 これらの手順は、ngClass を実装するために必要ではありません。

NgStyle を使用してインラインスタイルを設定する

コンポーネントに NgStyle をインポートする

NgStyle を使用するには、コンポーネントの imports リストに追加します。

src/app/app.component.ts (NgStyle インポート)

      
import {Component, OnInit} from '@angular/core';import {JsonPipe} from '@angular/common';import {NgIf} from '@angular/common';import {NgFor} from '@angular/common';import {NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common';import {NgStyle} from '@angular/common';import {NgClass} from '@angular/common';import {FormsModule} from '@angular/forms';import {Item} from './item';import {ItemDetailComponent} from './item-detail/item-detail.component';import {ItemSwitchComponents} from './item-switch.component';import {StoutItemComponent} from './item-switch.component';@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css'],  imports: [    NgIf, // <-- import into the component    NgFor, // <-- import into the component    NgStyle, // <-- import into the component    NgSwitch, // <-- import into the component    NgSwitchCase,    NgSwitchDefault,    NgClass, // <-- import into the component    FormsModule, // <--- import into the component    JsonPipe,    ItemDetailComponent,    ItemSwitchComponents,    StoutItemComponent,  ],})export class AppComponent implements OnInit {  canSave = true;  isSpecial = true;  isUnchanged = true;  isActive = true;  nullCustomer: string | null = null;  currentCustomer = {    name: 'Laura',  };  item!: Item; // defined to demonstrate template context precedence  items: Item[] = [];  currentItem!: Item;  // trackBy change counting  itemsNoTrackByCount = 0;  itemsWithTrackByCount = 0;  itemsWithTrackByCountReset = 0;  itemIdIncrement = 1;  currentClasses: Record<string, boolean> = {};  currentStyles: Record<string, string> = {};  ngOnInit() {    this.resetItems();    this.setCurrentClasses();    this.setCurrentStyles();    this.itemsNoTrackByCount = 0;  }  setUppercaseName(name: string) {    this.currentItem.name = name.toUpperCase();  }  setCurrentClasses() {    // CSS classes: added/removed per current state of component properties    this.currentClasses = {      saveable: this.canSave,      modified: !this.isUnchanged,      special: this.isSpecial,    };  }  setCurrentStyles() {    // CSS styles: set per current state of component properties    this.currentStyles = {      'font-style': this.canSave ? 'italic' : 'normal',      'font-weight': !this.isUnchanged ? 'bold' : 'normal',      'font-size': this.isSpecial ? '24px' : '12px',    };  }  isActiveToggle() {    this.isActive = !this.isActive;  }  giveNullCustomerValue() {    this.nullCustomer = 'Kelly';  }  resetItems() {    this.items = Item.items.map((item) => item.clone());    this.currentItem = this.items[0];    this.item = this.currentItem;  }  resetList() {    this.resetItems();    this.itemsWithTrackByCountReset = 0;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;  }  changeIds() {    this.items.forEach((i) => (i.id += 1 * this.itemIdIncrement));    this.itemsWithTrackByCountReset = -1;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;    this.itemsWithTrackByCount = ++this.itemsWithTrackByCount;  }  clearTrackByCounts() {    this.resetItems();    this.itemsNoTrackByCount = 0;    this.itemsWithTrackByCount = 0;    this.itemIdIncrement = 1;  }  trackByItems(index: number, item: Item): number {    return item.id;  }  trackById(index: number, item: any): number {    return item.id;  }  getValue(event: Event): string {    return (event.target as HTMLInputElement).value;  }}

NgStyle を使用して、コンポーネントの状態に基づいて、複数のインラインスタイルを同時に設定します。

  1. NgStyle を使用するには、コンポーネントクラスにメソッドを追加します。

    次の例では、setCurrentStyles() は3つの他のコンポーネントプロパティの状態に基づいて、3つのスタイルを定義するオブジェクトを使用して currentStyles プロパティを設定します。

    src/app/app.component.ts

          
    import {Component, OnInit} from '@angular/core';import {JsonPipe} from '@angular/common';import {NgIf} from '@angular/common';import {NgFor} from '@angular/common';import {NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common';import {NgStyle} from '@angular/common';import {NgClass} from '@angular/common';import {FormsModule} from '@angular/forms';import {Item} from './item';import {ItemDetailComponent} from './item-detail/item-detail.component';import {ItemSwitchComponents} from './item-switch.component';import {StoutItemComponent} from './item-switch.component';@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css'],  imports: [    NgIf, // <-- import into the component    NgFor, // <-- import into the component    NgStyle, // <-- import into the component    NgSwitch, // <-- import into the component    NgSwitchCase,    NgSwitchDefault,    NgClass, // <-- import into the component    FormsModule, // <--- import into the component    JsonPipe,    ItemDetailComponent,    ItemSwitchComponents,    StoutItemComponent,  ],})export class AppComponent implements OnInit {  canSave = true;  isSpecial = true;  isUnchanged = true;  isActive = true;  nullCustomer: string | null = null;  currentCustomer = {    name: 'Laura',  };  item!: Item; // defined to demonstrate template context precedence  items: Item[] = [];  currentItem!: Item;  // trackBy change counting  itemsNoTrackByCount = 0;  itemsWithTrackByCount = 0;  itemsWithTrackByCountReset = 0;  itemIdIncrement = 1;  currentClasses: Record<string, boolean> = {};  currentStyles: Record<string, string> = {};  ngOnInit() {    this.resetItems();    this.setCurrentClasses();    this.setCurrentStyles();    this.itemsNoTrackByCount = 0;  }  setUppercaseName(name: string) {    this.currentItem.name = name.toUpperCase();  }  setCurrentClasses() {    // CSS classes: added/removed per current state of component properties    this.currentClasses = {      saveable: this.canSave,      modified: !this.isUnchanged,      special: this.isSpecial,    };  }  setCurrentStyles() {    // CSS styles: set per current state of component properties    this.currentStyles = {      'font-style': this.canSave ? 'italic' : 'normal',      'font-weight': !this.isUnchanged ? 'bold' : 'normal',      'font-size': this.isSpecial ? '24px' : '12px',    };  }  isActiveToggle() {    this.isActive = !this.isActive;  }  giveNullCustomerValue() {    this.nullCustomer = 'Kelly';  }  resetItems() {    this.items = Item.items.map((item) => item.clone());    this.currentItem = this.items[0];    this.item = this.currentItem;  }  resetList() {    this.resetItems();    this.itemsWithTrackByCountReset = 0;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;  }  changeIds() {    this.items.forEach((i) => (i.id += 1 * this.itemIdIncrement));    this.itemsWithTrackByCountReset = -1;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;    this.itemsWithTrackByCount = ++this.itemsWithTrackByCount;  }  clearTrackByCounts() {    this.resetItems();    this.itemsNoTrackByCount = 0;    this.itemsWithTrackByCount = 0;    this.itemIdIncrement = 1;  }  trackByItems(index: number, item: Item): number {    return item.id;  }  trackById(index: number, item: any): number {    return item.id;  }  getValue(event: Event): string {    return (event.target as HTMLInputElement).value;  }}
  2. 要素のスタイルを設定するには、currentStyles に対する ngStyle プロパティバインディングを追加します。

    src/app/app.component.html

          
    <h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

このユースケースでは、Angularは初期化時と、変更が発生した場合にスタイルを適用します。 これを行うために、完全な例では、ngOnInit() を使用して最初に setCurrentStyles() を呼び出し、依存プロパティがボタンクリックを通じて変更されたときに呼び出します。 ただし、これらの手順は、ngStyle 自体を実装するために必要ではありません。

ngModel を使用してプロパティを表示および更新する

NgModel ディレクティブを使用して、データプロパティを表示し、ユーザーが変更を加えたときにそのプロパティを更新します。

  1. FormsModule をインポートし、AppComponentの imports リストに追加します。

    src/app/app.component.ts (FormsModule インポート)

          
    import {Component, OnInit} from '@angular/core';import {JsonPipe} from '@angular/common';import {NgIf} from '@angular/common';import {NgFor} from '@angular/common';import {NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common';import {NgStyle} from '@angular/common';import {NgClass} from '@angular/common';import {FormsModule} from '@angular/forms';import {Item} from './item';import {ItemDetailComponent} from './item-detail/item-detail.component';import {ItemSwitchComponents} from './item-switch.component';import {StoutItemComponent} from './item-switch.component';@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css'],  imports: [    NgIf, // <-- import into the component    NgFor, // <-- import into the component    NgStyle, // <-- import into the component    NgSwitch, // <-- import into the component    NgSwitchCase,    NgSwitchDefault,    NgClass, // <-- import into the component    FormsModule, // <--- import into the component    JsonPipe,    ItemDetailComponent,    ItemSwitchComponents,    StoutItemComponent,  ],})export class AppComponent implements OnInit {  canSave = true;  isSpecial = true;  isUnchanged = true;  isActive = true;  nullCustomer: string | null = null;  currentCustomer = {    name: 'Laura',  };  item!: Item; // defined to demonstrate template context precedence  items: Item[] = [];  currentItem!: Item;  // trackBy change counting  itemsNoTrackByCount = 0;  itemsWithTrackByCount = 0;  itemsWithTrackByCountReset = 0;  itemIdIncrement = 1;  currentClasses: Record<string, boolean> = {};  currentStyles: Record<string, string> = {};  ngOnInit() {    this.resetItems();    this.setCurrentClasses();    this.setCurrentStyles();    this.itemsNoTrackByCount = 0;  }  setUppercaseName(name: string) {    this.currentItem.name = name.toUpperCase();  }  setCurrentClasses() {    // CSS classes: added/removed per current state of component properties    this.currentClasses = {      saveable: this.canSave,      modified: !this.isUnchanged,      special: this.isSpecial,    };  }  setCurrentStyles() {    // CSS styles: set per current state of component properties    this.currentStyles = {      'font-style': this.canSave ? 'italic' : 'normal',      'font-weight': !this.isUnchanged ? 'bold' : 'normal',      'font-size': this.isSpecial ? '24px' : '12px',    };  }  isActiveToggle() {    this.isActive = !this.isActive;  }  giveNullCustomerValue() {    this.nullCustomer = 'Kelly';  }  resetItems() {    this.items = Item.items.map((item) => item.clone());    this.currentItem = this.items[0];    this.item = this.currentItem;  }  resetList() {    this.resetItems();    this.itemsWithTrackByCountReset = 0;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;  }  changeIds() {    this.items.forEach((i) => (i.id += 1 * this.itemIdIncrement));    this.itemsWithTrackByCountReset = -1;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;    this.itemsWithTrackByCount = ++this.itemsWithTrackByCount;  }  clearTrackByCounts() {    this.resetItems();    this.itemsNoTrackByCount = 0;    this.itemsWithTrackByCount = 0;    this.itemIdIncrement = 1;  }  trackByItems(index: number, item: Item): number {    return item.id;  }  trackById(index: number, item: any): number {    return item.id;  }  getValue(event: Event): string {    return (event.target as HTMLInputElement).value;  }}
  2. HTML <form> 要素に [(ngModel)] バインディングを追加して、プロパティ(ここでは name)に等しく設定します。

    src/app/app.component.html (NgModel の例)

          
    <h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

    この [(ngModel)] 構文は、データバインドプロパティのみを設定できます。

構成をカスタマイズするには、拡張フォームを記述します。これにより、プロパティとイベントバインディングが分離されます。 プロパティバインディング を使用してプロパティを設定し、イベントバインディング を使用して変更に応答します。 次の例では、<input> 値を大文字に変更します。

src/app/app.component.html

      
<h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

以下は、大文字バージョンを含む、すべてのバリエーションが動作している様子です。

NgModel のバリエーション

NgModel と値アクセサー

NgModel ディレクティブは、ControlValueAccessor によってサポートされている要素で機能します。 Angularは、すべての基本的なHTMLフォーム要素に対して 値アクセサー を提供します。 詳細については、フォーム を参照してください。

[(ngModel)] を非フォームの組み込み要素またはサードパーティのカスタムコンポーネントに適用するには、値アクセサーを作成する必要があります。 詳細については、DefaultValueAccessor に関するAPIドキュメントを参照してください。

HELPFUL: Angularコンポーネントを作成する際、Angularの 双方向バインディング構文 に従って値とイベントプロパティに名前を付ければ、値アクセサーや NgModel は必要ありません。

組み込み構造ディレクティブ

構造ディレクティブは、HTMLレイアウトを担当します。 これらは、通常、付加されているホスト要素を追加、削除、および操作することによって、DOMの構造を形成または再形成します。

このセクションでは、最も一般的な組み込み構造ディレクティブを紹介します。

一般的な組み込み構造ディレクティブ 詳細
NgIf テンプレートからサブビューを条件付きで作成または破棄します。
NgFor リスト内の各アイテムに対してノードを繰り返します。
NgSwitch 代替ビューを切り替えるディレクティブのセットです。

詳細については、構造ディレクティブ を参照してください。

NgIf を使用して要素を追加または削除する

ホスト要素に NgIf ディレクティブを適用することによって、要素を追加または削除します。

NgIffalse の場合、Angularは要素とその子孫をDOMから削除します。 次に、Angularはそれらのコンポーネントを破棄し、メモリとリソースを解放します。

コンポーネントに NgIf をインポートする

NgIf を使用するには、コンポーネントの imports リストに追加します。

src/app/app.component.ts (NgIf インポート)

      
import {Component, OnInit} from '@angular/core';import {JsonPipe} from '@angular/common';import {NgIf} from '@angular/common';import {NgFor} from '@angular/common';import {NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common';import {NgStyle} from '@angular/common';import {NgClass} from '@angular/common';import {FormsModule} from '@angular/forms';import {Item} from './item';import {ItemDetailComponent} from './item-detail/item-detail.component';import {ItemSwitchComponents} from './item-switch.component';import {StoutItemComponent} from './item-switch.component';@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css'],  imports: [    NgIf, // <-- import into the component    NgFor, // <-- import into the component    NgStyle, // <-- import into the component    NgSwitch, // <-- import into the component    NgSwitchCase,    NgSwitchDefault,    NgClass, // <-- import into the component    FormsModule, // <--- import into the component    JsonPipe,    ItemDetailComponent,    ItemSwitchComponents,    StoutItemComponent,  ],})export class AppComponent implements OnInit {  canSave = true;  isSpecial = true;  isUnchanged = true;  isActive = true;  nullCustomer: string | null = null;  currentCustomer = {    name: 'Laura',  };  item!: Item; // defined to demonstrate template context precedence  items: Item[] = [];  currentItem!: Item;  // trackBy change counting  itemsNoTrackByCount = 0;  itemsWithTrackByCount = 0;  itemsWithTrackByCountReset = 0;  itemIdIncrement = 1;  currentClasses: Record<string, boolean> = {};  currentStyles: Record<string, string> = {};  ngOnInit() {    this.resetItems();    this.setCurrentClasses();    this.setCurrentStyles();    this.itemsNoTrackByCount = 0;  }  setUppercaseName(name: string) {    this.currentItem.name = name.toUpperCase();  }  setCurrentClasses() {    // CSS classes: added/removed per current state of component properties    this.currentClasses = {      saveable: this.canSave,      modified: !this.isUnchanged,      special: this.isSpecial,    };  }  setCurrentStyles() {    // CSS styles: set per current state of component properties    this.currentStyles = {      'font-style': this.canSave ? 'italic' : 'normal',      'font-weight': !this.isUnchanged ? 'bold' : 'normal',      'font-size': this.isSpecial ? '24px' : '12px',    };  }  isActiveToggle() {    this.isActive = !this.isActive;  }  giveNullCustomerValue() {    this.nullCustomer = 'Kelly';  }  resetItems() {    this.items = Item.items.map((item) => item.clone());    this.currentItem = this.items[0];    this.item = this.currentItem;  }  resetList() {    this.resetItems();    this.itemsWithTrackByCountReset = 0;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;  }  changeIds() {    this.items.forEach((i) => (i.id += 1 * this.itemIdIncrement));    this.itemsWithTrackByCountReset = -1;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;    this.itemsWithTrackByCount = ++this.itemsWithTrackByCount;  }  clearTrackByCounts() {    this.resetItems();    this.itemsNoTrackByCount = 0;    this.itemsWithTrackByCount = 0;    this.itemIdIncrement = 1;  }  trackByItems(index: number, item: Item): number {    return item.id;  }  trackById(index: number, item: any): number {    return item.id;  }  getValue(event: Event): string {    return (event.target as HTMLInputElement).value;  }}

NgIf を使用

要素を追加または削除するには、次の例のように、*ngIf を条件式(例: isActive)にバインドします。

src/app/app.component.html

      
<h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

isActive 式が真の値を返す場合、NgIfItemDetailComponent をDOMに追加します。 式が偽の場合、NgIfItemDetailComponent をDOMから削除し、コンポーネントとそのすべてのサブコンポーネントを破棄します。

NgIfNgIfElse の詳細については、NgIf API ドキュメント を参照してください。

null に対する保護

デフォルトでは、NgIfnull 値にバインドされた要素の表示を防ぎます。

NgIf を使用して <div> を保護するには、<div>*ngIf="yourProperty" を追加します。 次の例では、currentCustomer が存在するため、currentCustomer の名前が表示されます。

src/app/app.component.html

      
<h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

ただし、プロパティが null の場合、Angularは <div> を表示しません。 この例では、nullCustomernull であるため、Angularは nullCustomer を表示しません。

src/app/app.component.html

      
<h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

NgFor を使用してアイテムを一覧表示する

NgFor ディレクティブを使用して、アイテムのリストを表示します。

コンポーネントに NgFor をインポートする

NgFor を使用するには、コンポーネントの imports リストに追加します。

src/app/app.component.ts (NgFor インポート)

      
import {Component, OnInit} from '@angular/core';import {JsonPipe} from '@angular/common';import {NgIf} from '@angular/common';import {NgFor} from '@angular/common';import {NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common';import {NgStyle} from '@angular/common';import {NgClass} from '@angular/common';import {FormsModule} from '@angular/forms';import {Item} from './item';import {ItemDetailComponent} from './item-detail/item-detail.component';import {ItemSwitchComponents} from './item-switch.component';import {StoutItemComponent} from './item-switch.component';@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css'],  imports: [    NgIf, // <-- import into the component    NgFor, // <-- import into the component    NgStyle, // <-- import into the component    NgSwitch, // <-- import into the component    NgSwitchCase,    NgSwitchDefault,    NgClass, // <-- import into the component    FormsModule, // <--- import into the component    JsonPipe,    ItemDetailComponent,    ItemSwitchComponents,    StoutItemComponent,  ],})export class AppComponent implements OnInit {  canSave = true;  isSpecial = true;  isUnchanged = true;  isActive = true;  nullCustomer: string | null = null;  currentCustomer = {    name: 'Laura',  };  item!: Item; // defined to demonstrate template context precedence  items: Item[] = [];  currentItem!: Item;  // trackBy change counting  itemsNoTrackByCount = 0;  itemsWithTrackByCount = 0;  itemsWithTrackByCountReset = 0;  itemIdIncrement = 1;  currentClasses: Record<string, boolean> = {};  currentStyles: Record<string, string> = {};  ngOnInit() {    this.resetItems();    this.setCurrentClasses();    this.setCurrentStyles();    this.itemsNoTrackByCount = 0;  }  setUppercaseName(name: string) {    this.currentItem.name = name.toUpperCase();  }  setCurrentClasses() {    // CSS classes: added/removed per current state of component properties    this.currentClasses = {      saveable: this.canSave,      modified: !this.isUnchanged,      special: this.isSpecial,    };  }  setCurrentStyles() {    // CSS styles: set per current state of component properties    this.currentStyles = {      'font-style': this.canSave ? 'italic' : 'normal',      'font-weight': !this.isUnchanged ? 'bold' : 'normal',      'font-size': this.isSpecial ? '24px' : '12px',    };  }  isActiveToggle() {    this.isActive = !this.isActive;  }  giveNullCustomerValue() {    this.nullCustomer = 'Kelly';  }  resetItems() {    this.items = Item.items.map((item) => item.clone());    this.currentItem = this.items[0];    this.item = this.currentItem;  }  resetList() {    this.resetItems();    this.itemsWithTrackByCountReset = 0;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;  }  changeIds() {    this.items.forEach((i) => (i.id += 1 * this.itemIdIncrement));    this.itemsWithTrackByCountReset = -1;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;    this.itemsWithTrackByCount = ++this.itemsWithTrackByCount;  }  clearTrackByCounts() {    this.resetItems();    this.itemsNoTrackByCount = 0;    this.itemsWithTrackByCount = 0;    this.itemIdIncrement = 1;  }  trackByItems(index: number, item: Item): number {    return item.id;  }  trackById(index: number, item: any): number {    return item.id;  }  getValue(event: Event): string {    return (event.target as HTMLInputElement).value;  }}

NgFor を使用

NgFor を使用するには、以下を行う必要があります。

  1. Angularが単一のアイテムをどのようにレンダリングするかを決定するHTMLブロックを定義します。
  2. アイテムを一覧表示するには、*ngForlet item of items という省略記号を割り当てます。

src/app/app.component.html

      
<h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

文字列 "let item of items" は、Angularに以下のことを指示します。

  • items 配列の各アイテムを、ローカルの item ループ変数に格納します
  • 各アイテムを、各反復のテンプレート化されたHTMLで使用できるようにします
  • "let item of items" を、ホスト要素の周りの <ng-template> に変換します
  • リストの各 item に対して、<ng-template> を繰り返します

詳細については、構造ディレクティブの省略記号 セクションの 構造ディレクティブ を参照してください。

コンポーネントビューを繰り返す

コンポーネント要素を繰り返すには、セレクターに *ngFor を適用します。 次の例では、セレクターは <app-item-detail> です。

src/app/app.component.html

      
<h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

次の場所で、テンプレート入力変数(例: item)を参照します。

  • ngFor ホスト要素内
  • アイテムのプロパティにアクセスするために、ホスト要素の子孫内

次の例では、最初に補間で item を参照し、次に <app-item-detail> コンポーネントの item プロパティにバインディングを渡します。

src/app/app.component.html

      
<h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

テンプレート入力変数の詳細については、構造ディレクティブの省略記号 を参照してください。

*ngForindex を取得する

テンプレート入力変数で *ngForindex を取得し、テンプレート内で使用します。

*ngFor の省略記号に、セミコロンと let i=index を追加します。 次の例では、i という名前の変数に index を取得し、アイテム名とともに表示します。

src/app/app.component.html

      
<h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

NgFor ディレクティブコンテキストのindexプロパティは、各反復におけるアイテムの0ベースのインデックスを返します。

Angularはこの命令をホスト要素の周りの <ng-template> に変換し、 次にこのテンプレートを繰り返し使用して、 リストの各 item に対して新しい要素とバインディングのセットを作成します。 省略記号の詳細については、構造ディレクティブ ガイドを参照してください。

条件が真の場合に要素を繰り返す

特定の条件が真の場合にHTMLブロックを繰り返すには、*ngFor 要素をラップするコンテナ要素に *ngIf を置きます。

詳細については、要素ごとの構造ディレクティブ を参照してください。

*ngFor trackBy を使用してアイテムを追跡する

アプリケーションがサーバーに送信する呼び出しの数を減らすには、アイテムリストへの変更を追跡します。 *ngFortrackBy プロパティを使用すると、Angularは、アイテムリスト全体をリロードするのではなく、変更されたアイテムのみを変更して再レンダリングできます。

  1. NgFor が追跡する必要がある値を返すメソッドをコンポーネントに追加します。 この例では、追跡する必要がある値はアイテムの id です。 ブラウザがすでに id をレンダリングしている場合、Angularはそれを追跡し、同じ id についてサーバーに再クエリすることはありません。

    src/app/app.component.ts

          
    import {Component, OnInit} from '@angular/core';import {JsonPipe} from '@angular/common';import {NgIf} from '@angular/common';import {NgFor} from '@angular/common';import {NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common';import {NgStyle} from '@angular/common';import {NgClass} from '@angular/common';import {FormsModule} from '@angular/forms';import {Item} from './item';import {ItemDetailComponent} from './item-detail/item-detail.component';import {ItemSwitchComponents} from './item-switch.component';import {StoutItemComponent} from './item-switch.component';@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css'],  imports: [    NgIf, // <-- import into the component    NgFor, // <-- import into the component    NgStyle, // <-- import into the component    NgSwitch, // <-- import into the component    NgSwitchCase,    NgSwitchDefault,    NgClass, // <-- import into the component    FormsModule, // <--- import into the component    JsonPipe,    ItemDetailComponent,    ItemSwitchComponents,    StoutItemComponent,  ],})export class AppComponent implements OnInit {  canSave = true;  isSpecial = true;  isUnchanged = true;  isActive = true;  nullCustomer: string | null = null;  currentCustomer = {    name: 'Laura',  };  item!: Item; // defined to demonstrate template context precedence  items: Item[] = [];  currentItem!: Item;  // trackBy change counting  itemsNoTrackByCount = 0;  itemsWithTrackByCount = 0;  itemsWithTrackByCountReset = 0;  itemIdIncrement = 1;  currentClasses: Record<string, boolean> = {};  currentStyles: Record<string, string> = {};  ngOnInit() {    this.resetItems();    this.setCurrentClasses();    this.setCurrentStyles();    this.itemsNoTrackByCount = 0;  }  setUppercaseName(name: string) {    this.currentItem.name = name.toUpperCase();  }  setCurrentClasses() {    // CSS classes: added/removed per current state of component properties    this.currentClasses = {      saveable: this.canSave,      modified: !this.isUnchanged,      special: this.isSpecial,    };  }  setCurrentStyles() {    // CSS styles: set per current state of component properties    this.currentStyles = {      'font-style': this.canSave ? 'italic' : 'normal',      'font-weight': !this.isUnchanged ? 'bold' : 'normal',      'font-size': this.isSpecial ? '24px' : '12px',    };  }  isActiveToggle() {    this.isActive = !this.isActive;  }  giveNullCustomerValue() {    this.nullCustomer = 'Kelly';  }  resetItems() {    this.items = Item.items.map((item) => item.clone());    this.currentItem = this.items[0];    this.item = this.currentItem;  }  resetList() {    this.resetItems();    this.itemsWithTrackByCountReset = 0;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;  }  changeIds() {    this.items.forEach((i) => (i.id += 1 * this.itemIdIncrement));    this.itemsWithTrackByCountReset = -1;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;    this.itemsWithTrackByCount = ++this.itemsWithTrackByCount;  }  clearTrackByCounts() {    this.resetItems();    this.itemsNoTrackByCount = 0;    this.itemsWithTrackByCount = 0;    this.itemIdIncrement = 1;  }  trackByItems(index: number, item: Item): number {    return item.id;  }  trackById(index: number, item: any): number {    return item.id;  }  getValue(event: Event): string {    return (event.target as HTMLInputElement).value;  }}
  2. 省略記号式で、trackBytrackByItems() メソッドに設定します。

    src/app/app.component.html

          
    <h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

Change ids は、新しい item.id を持つ新しいアイテムを作成します。 trackBy の効果の次の図では、Reset items は、同じ item.id を持つ新しいアイテムを作成します。

  • trackBy がない場合、両方のボタンがDOM要素の完全な置き換えをトリガーします。
  • trackBy がある場合、id の変更のみが要素の置き換えをトリガーします。
trackBy のアニメーション

DOM 要素のないディレクティブをホストする

Angularの <ng-container> は、AngularがDOMに配置しないため、スタイルやレイアウトに影響を与えないグループ化要素です。

ディレクティブをホストする単一の要素がない場合は、<ng-container> を使用します。

以下は、<ng-container> を使用した条件付きのパラグラフです。

src/app/app.component.html (ngif-ngcontainer)

      
<h1>Structural Directives</h1><p>Conditional display of hero</p><blockquote><div *ngIf="hero" class="name">{{hero.name}}</div></blockquote><p>List of heroes</p><ul>  <li *ngFor="let hero of heroes">{{hero.name}}</li></ul><hr><h2 id="ngIf">NgIf</h2><p *ngIf="true">  Expression is true and ngIf is true.  This paragraph is in the DOM.</p><p *ngIf="false">  Expression is false and ngIf is false.  This paragraph is not in the DOM.</p><p [style.display]="'block'">  Expression sets display to "block".  This paragraph is visible.</p><p [style.display]="'none'">  Expression sets display to "none".  This paragraph is hidden but still in the DOM.</p><h4>NgIf with template</h4><p><ng-template> element</p><ng-template [ngIf]="hero">  <div class="name">{{hero.name}}</div></ng-template><hr><h2 id="ng-container"><ng-container></h2><h4>*ngIf with a <ng-container></h4><button type="button" (click)="hero = hero ? null : heroes[0]">Toggle hero</button><p>  I turned the corner  <ng-container *ngIf="hero">    and saw {{hero.name}}. I waved  </ng-container>  and continued on my way.</p><p>  I turned the corner  <span *ngIf="hero">    and saw {{hero.name}}. I waved  </span>  and continued on my way.</p><p><em><select> with <span></em></p><div>  Pick your favorite hero  (<label for="show-sad"><input id="show-sad" type="checkbox" checked (change)="showSad = !showSad">show sad</label>)</div><select [(ngModel)]="hero">  <span *ngFor="let h of heroes">    <span *ngIf="showSad || h.emotion !== 'sad'">      <option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>    </span>  </span></select><p><em><select> with <ng-container></em></p><div>  Pick your favorite hero  (<label for="showSad"><input id="showSad" type="checkbox" checked (change)="showSad = !showSad">show sad</label>)</div><select [(ngModel)]="hero">  <ng-container *ngFor="let h of heroes">    <ng-container *ngIf="showSad || h.emotion !== 'sad'">      <option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>    </ng-container>  </ng-container></select><br><br><hr><h2 id="ngFor">NgFor</h2><div class="box"><p class="code"><div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd"></p><div  *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById"  [class.odd]="odd">  ({{i}}) {{hero.name}}</div><p class="code"><ng-template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" [ngForTrackBy]="trackById"/></p><ng-template ngFor let-hero [ngForOf]="heroes"  let-i="index" let-odd="odd" [ngForTrackBy]="trackById">  <div [class.odd]="odd">    ({{i}}) {{hero.name}}  </div></ng-template></div><hr><h2 id="ngSwitch">NgSwitch</h2><div>Pick your favorite hero</div><p>  <label for="hero-{{h}}" *ngFor="let h of heroes">    <input id="hero-{{h}}" type="radio" name="heroes" [(ngModel)]="hero" [value]="h">{{h.name}}  </label>  <label for="none-of-the-above"><input id="none-of-the-above" type="radio" name="heroes" (click)="hero = null">None of the above</label></p><h4>NgSwitch</h4><div [ngSwitch]="hero?.emotion">  <app-happy-hero    *ngSwitchCase="'happy'"    [hero]="hero!"></app-happy-hero>  <app-sad-hero      *ngSwitchCase="'sad'"      [hero]="hero!"></app-sad-hero>  <app-confused-hero *ngSwitchCase="'confused'" [hero]="hero!"></app-confused-hero>  <app-unknown-hero  *ngSwitchDefault           [hero]="hero!"></app-unknown-hero></div><h4>NgSwitch with <ng-template></h4><div [ngSwitch]="hero?.emotion">  <ng-template ngSwitchCase="happy">    <app-happy-hero [hero]="hero!"></app-happy-hero>  </ng-template>  <ng-template ngSwitchCase="sad">    <app-sad-hero [hero]="hero!"></app-sad-hero>  </ng-template>  <ng-template ngSwitchCase="confused">    <app-confused-hero [hero]="hero!"></app-confused-hero>  </ng-template >  <ng-template ngSwitchDefault>    <app-unknown-hero [hero]="hero!"></app-unknown-hero>  </ng-template></div><hr><h2 id="appUnless">UnlessDirective</h2><p>  The condition is currently  <span [ngClass]="{ 'a': !condition, 'b': condition, 'unless': true }">{{condition}}</span>.  <button    type="button"    (click)="condition = !condition"    [ngClass] = "{ 'a': condition, 'b': !condition }" >    Toggle condition to {{condition ? 'false' : 'true'}}  </button></p><p *appUnless="condition" class="unless a">  (A) This paragraph is displayed because the condition is false.</p><p *appUnless="!condition" class="unless b">  (B) Although the condition is true,  this paragraph is displayed because appUnless is set to false.</p><h4>UnlessDirective with template</h4><p *appUnless="condition">Show this sentence unless the condition is true.</p><p *appUnless="condition" class="code unless">  (A) <p *appUnless="condition" class="code unless"></p><ng-template [appUnless]="condition">  <p class="code unless">    (A) <ng-template [appUnless]="condition">  </p></ng-template><hr /><h2 id="appIfLoaded">IfLoadedDirective</h2><app-hero></app-hero><hr /><h2 id="appTrigonometry">TrigonometryDirective</h2><ul *appTrigonometry="30; sin as s; cos as c; tan as t">  <li>sin(30°): {{ s }}</li>  <li>cos(30°): {{ c }}</li>  <li>tan(30°): {{ t }}</li></ul>
適切なスタイルが適用された ngcontainer パラグラフ
  1. FormsModule から ngModel ディレクティブをインポートします。

  2. FormsModule を、関連するAngularモジュールのインポートセクションに追加します。

  3. <option> を条件付きで除外するには、<option><ng-container> でラップします。

    src/app/app.component.html (select-ngcontainer)

          
    <h1>Structural Directives</h1><p>Conditional display of hero</p><blockquote><div *ngIf="hero" class="name">{{hero.name}}</div></blockquote><p>List of heroes</p><ul>  <li *ngFor="let hero of heroes">{{hero.name}}</li></ul><hr><h2 id="ngIf">NgIf</h2><p *ngIf="true">  Expression is true and ngIf is true.  This paragraph is in the DOM.</p><p *ngIf="false">  Expression is false and ngIf is false.  This paragraph is not in the DOM.</p><p [style.display]="'block'">  Expression sets display to "block".  This paragraph is visible.</p><p [style.display]="'none'">  Expression sets display to "none".  This paragraph is hidden but still in the DOM.</p><h4>NgIf with template</h4><p><ng-template> element</p><ng-template [ngIf]="hero">  <div class="name">{{hero.name}}</div></ng-template><hr><h2 id="ng-container"><ng-container></h2><h4>*ngIf with a <ng-container></h4><button type="button" (click)="hero = hero ? null : heroes[0]">Toggle hero</button><p>  I turned the corner  <ng-container *ngIf="hero">    and saw {{hero.name}}. I waved  </ng-container>  and continued on my way.</p><p>  I turned the corner  <span *ngIf="hero">    and saw {{hero.name}}. I waved  </span>  and continued on my way.</p><p><em><select> with <span></em></p><div>  Pick your favorite hero  (<label for="show-sad"><input id="show-sad" type="checkbox" checked (change)="showSad = !showSad">show sad</label>)</div><select [(ngModel)]="hero">  <span *ngFor="let h of heroes">    <span *ngIf="showSad || h.emotion !== 'sad'">      <option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>    </span>  </span></select><p><em><select> with <ng-container></em></p><div>  Pick your favorite hero  (<label for="showSad"><input id="showSad" type="checkbox" checked (change)="showSad = !showSad">show sad</label>)</div><select [(ngModel)]="hero">  <ng-container *ngFor="let h of heroes">    <ng-container *ngIf="showSad || h.emotion !== 'sad'">      <option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>    </ng-container>  </ng-container></select><br><br><hr><h2 id="ngFor">NgFor</h2><div class="box"><p class="code"><div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd"></p><div  *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById"  [class.odd]="odd">  ({{i}}) {{hero.name}}</div><p class="code"><ng-template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" [ngForTrackBy]="trackById"/></p><ng-template ngFor let-hero [ngForOf]="heroes"  let-i="index" let-odd="odd" [ngForTrackBy]="trackById">  <div [class.odd]="odd">    ({{i}}) {{hero.name}}  </div></ng-template></div><hr><h2 id="ngSwitch">NgSwitch</h2><div>Pick your favorite hero</div><p>  <label for="hero-{{h}}" *ngFor="let h of heroes">    <input id="hero-{{h}}" type="radio" name="heroes" [(ngModel)]="hero" [value]="h">{{h.name}}  </label>  <label for="none-of-the-above"><input id="none-of-the-above" type="radio" name="heroes" (click)="hero = null">None of the above</label></p><h4>NgSwitch</h4><div [ngSwitch]="hero?.emotion">  <app-happy-hero    *ngSwitchCase="'happy'"    [hero]="hero!"></app-happy-hero>  <app-sad-hero      *ngSwitchCase="'sad'"      [hero]="hero!"></app-sad-hero>  <app-confused-hero *ngSwitchCase="'confused'" [hero]="hero!"></app-confused-hero>  <app-unknown-hero  *ngSwitchDefault           [hero]="hero!"></app-unknown-hero></div><h4>NgSwitch with <ng-template></h4><div [ngSwitch]="hero?.emotion">  <ng-template ngSwitchCase="happy">    <app-happy-hero [hero]="hero!"></app-happy-hero>  </ng-template>  <ng-template ngSwitchCase="sad">    <app-sad-hero [hero]="hero!"></app-sad-hero>  </ng-template>  <ng-template ngSwitchCase="confused">    <app-confused-hero [hero]="hero!"></app-confused-hero>  </ng-template >  <ng-template ngSwitchDefault>    <app-unknown-hero [hero]="hero!"></app-unknown-hero>  </ng-template></div><hr><h2 id="appUnless">UnlessDirective</h2><p>  The condition is currently  <span [ngClass]="{ 'a': !condition, 'b': condition, 'unless': true }">{{condition}}</span>.  <button    type="button"    (click)="condition = !condition"    [ngClass] = "{ 'a': condition, 'b': !condition }" >    Toggle condition to {{condition ? 'false' : 'true'}}  </button></p><p *appUnless="condition" class="unless a">  (A) This paragraph is displayed because the condition is false.</p><p *appUnless="!condition" class="unless b">  (B) Although the condition is true,  this paragraph is displayed because appUnless is set to false.</p><h4>UnlessDirective with template</h4><p *appUnless="condition">Show this sentence unless the condition is true.</p><p *appUnless="condition" class="code unless">  (A) <p *appUnless="condition" class="code unless"></p><ng-template [appUnless]="condition">  <p class="code unless">    (A) <ng-template [appUnless]="condition">  </p></ng-template><hr /><h2 id="appIfLoaded">IfLoadedDirective</h2><app-hero></app-hero><hr /><h2 id="appTrigonometry">TrigonometryDirective</h2><ul *appTrigonometry="30; sin as s; cos as c; tan as t">  <li>sin(30°): {{ s }}</li>  <li>cos(30°): {{ c }}</li>  <li>tan(30°): {{ t }}</li></ul>
    ngcontainer オプションは正しく機能します

NgSwitch を使用してケースを切り替える

JavaScriptの switch ステートメントと同様に、NgSwitch は、スイッチ条件に基づいて、いくつかの可能な要素の中から1つの要素を表示します。 Angularは、選択された要素のみをDOMに配置します。

NgSwitch は、3つのディレクティブのセットです。

NgSwitch ディレクティブ 詳細
NgSwitch 仲間のディレクティブの動作を変更する属性ディレクティブ。
NgSwitchCase バインドされた値がスイッチ値と等しい場合に、その要素を DOM に追加し、バインドされた値がスイッチ値と等しくない場合に、その要素を DOM から削除する構造ディレクティブ。
NgSwitchDefault 選択された NgSwitchCase がない場合に、その要素を DOM に追加する構造ディレクティブ。

ディレクティブを使用するには、NgSwitchNgSwitchCase、および NgSwitchDefault をコンポーネントの imports リストに追加します。

src/app/app.component.ts (NgSwitch インポート)

      
import {Component, OnInit} from '@angular/core';import {JsonPipe} from '@angular/common';import {NgIf} from '@angular/common';import {NgFor} from '@angular/common';import {NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common';import {NgStyle} from '@angular/common';import {NgClass} from '@angular/common';import {FormsModule} from '@angular/forms';import {Item} from './item';import {ItemDetailComponent} from './item-detail/item-detail.component';import {ItemSwitchComponents} from './item-switch.component';import {StoutItemComponent} from './item-switch.component';@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css'],  imports: [    NgIf, // <-- import into the component    NgFor, // <-- import into the component    NgStyle, // <-- import into the component    NgSwitch, // <-- import into the component    NgSwitchCase,    NgSwitchDefault,    NgClass, // <-- import into the component    FormsModule, // <--- import into the component    JsonPipe,    ItemDetailComponent,    ItemSwitchComponents,    StoutItemComponent,  ],})export class AppComponent implements OnInit {  canSave = true;  isSpecial = true;  isUnchanged = true;  isActive = true;  nullCustomer: string | null = null;  currentCustomer = {    name: 'Laura',  };  item!: Item; // defined to demonstrate template context precedence  items: Item[] = [];  currentItem!: Item;  // trackBy change counting  itemsNoTrackByCount = 0;  itemsWithTrackByCount = 0;  itemsWithTrackByCountReset = 0;  itemIdIncrement = 1;  currentClasses: Record<string, boolean> = {};  currentStyles: Record<string, string> = {};  ngOnInit() {    this.resetItems();    this.setCurrentClasses();    this.setCurrentStyles();    this.itemsNoTrackByCount = 0;  }  setUppercaseName(name: string) {    this.currentItem.name = name.toUpperCase();  }  setCurrentClasses() {    // CSS classes: added/removed per current state of component properties    this.currentClasses = {      saveable: this.canSave,      modified: !this.isUnchanged,      special: this.isSpecial,    };  }  setCurrentStyles() {    // CSS styles: set per current state of component properties    this.currentStyles = {      'font-style': this.canSave ? 'italic' : 'normal',      'font-weight': !this.isUnchanged ? 'bold' : 'normal',      'font-size': this.isSpecial ? '24px' : '12px',    };  }  isActiveToggle() {    this.isActive = !this.isActive;  }  giveNullCustomerValue() {    this.nullCustomer = 'Kelly';  }  resetItems() {    this.items = Item.items.map((item) => item.clone());    this.currentItem = this.items[0];    this.item = this.currentItem;  }  resetList() {    this.resetItems();    this.itemsWithTrackByCountReset = 0;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;  }  changeIds() {    this.items.forEach((i) => (i.id += 1 * this.itemIdIncrement));    this.itemsWithTrackByCountReset = -1;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;    this.itemsWithTrackByCount = ++this.itemsWithTrackByCount;  }  clearTrackByCounts() {    this.resetItems();    this.itemsNoTrackByCount = 0;    this.itemsWithTrackByCount = 0;    this.itemIdIncrement = 1;  }  trackByItems(index: number, item: Item): number {    return item.id;  }  trackById(index: number, item: any): number {    return item.id;  }  getValue(event: Event): string {    return (event.target as HTMLInputElement).value;  }}

NgSwitch を使用

  1. <div> などの要素に、[ngSwitch] を追加し、スイッチ値を返す式(例: feature)にバインドします。 この例の feature 値は文字列ですが、スイッチ値は任意の型にできます。

  2. ケースの要素に、*ngSwitchCase*ngSwitchDefault にバインドします。

    src/app/app.component.html

          
    <h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>
  3. 親コンポーネントで、[ngSwitch] 式で使用する currentItem を定義します。

    src/app/app.component.ts

          
    import {Component, OnInit} from '@angular/core';import {JsonPipe} from '@angular/common';import {NgIf} from '@angular/common';import {NgFor} from '@angular/common';import {NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common';import {NgStyle} from '@angular/common';import {NgClass} from '@angular/common';import {FormsModule} from '@angular/forms';import {Item} from './item';import {ItemDetailComponent} from './item-detail/item-detail.component';import {ItemSwitchComponents} from './item-switch.component';import {StoutItemComponent} from './item-switch.component';@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css'],  imports: [    NgIf, // <-- import into the component    NgFor, // <-- import into the component    NgStyle, // <-- import into the component    NgSwitch, // <-- import into the component    NgSwitchCase,    NgSwitchDefault,    NgClass, // <-- import into the component    FormsModule, // <--- import into the component    JsonPipe,    ItemDetailComponent,    ItemSwitchComponents,    StoutItemComponent,  ],})export class AppComponent implements OnInit {  canSave = true;  isSpecial = true;  isUnchanged = true;  isActive = true;  nullCustomer: string | null = null;  currentCustomer = {    name: 'Laura',  };  item!: Item; // defined to demonstrate template context precedence  items: Item[] = [];  currentItem!: Item;  // trackBy change counting  itemsNoTrackByCount = 0;  itemsWithTrackByCount = 0;  itemsWithTrackByCountReset = 0;  itemIdIncrement = 1;  currentClasses: Record<string, boolean> = {};  currentStyles: Record<string, string> = {};  ngOnInit() {    this.resetItems();    this.setCurrentClasses();    this.setCurrentStyles();    this.itemsNoTrackByCount = 0;  }  setUppercaseName(name: string) {    this.currentItem.name = name.toUpperCase();  }  setCurrentClasses() {    // CSS classes: added/removed per current state of component properties    this.currentClasses = {      saveable: this.canSave,      modified: !this.isUnchanged,      special: this.isSpecial,    };  }  setCurrentStyles() {    // CSS styles: set per current state of component properties    this.currentStyles = {      'font-style': this.canSave ? 'italic' : 'normal',      'font-weight': !this.isUnchanged ? 'bold' : 'normal',      'font-size': this.isSpecial ? '24px' : '12px',    };  }  isActiveToggle() {    this.isActive = !this.isActive;  }  giveNullCustomerValue() {    this.nullCustomer = 'Kelly';  }  resetItems() {    this.items = Item.items.map((item) => item.clone());    this.currentItem = this.items[0];    this.item = this.currentItem;  }  resetList() {    this.resetItems();    this.itemsWithTrackByCountReset = 0;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;  }  changeIds() {    this.items.forEach((i) => (i.id += 1 * this.itemIdIncrement));    this.itemsWithTrackByCountReset = -1;    this.itemsNoTrackByCount = ++this.itemsNoTrackByCount;    this.itemsWithTrackByCount = ++this.itemsWithTrackByCount;  }  clearTrackByCounts() {    this.resetItems();    this.itemsNoTrackByCount = 0;    this.itemsWithTrackByCount = 0;    this.itemIdIncrement = 1;  }  trackByItems(index: number, item: Item): number {    return item.id;  }  trackById(index: number, item: any): number {    return item.id;  }  getValue(event: Event): string {    return (event.target as HTMLInputElement).value;  }}
  4. 各子コンポーネントで、親コンポーネントの currentItem にバインドされた item 入力プロパティ を追加します。 次の2つのスニペットは、親コンポーネントと子コンポーネントの1つを示しています。 他の子コンポーネントは、StoutItemComponent と同じです。

    各子コンポーネント(ここでは StoutItemComponent)

          
    import {Component, Input} from '@angular/core';import {Item} from './item';@Component({  selector: 'app-stout-item',  template: "I'm a little {{item.name}}, short and stout!",})export class StoutItemComponent {  @Input() item!: Item;}@Component({  selector: 'app-best-item',  template: 'This is the brightest {{item.name}} in town.',})export class BestItemComponent {  @Input() item!: Item;}@Component({  selector: 'app-device-item',  template: 'Which is the slimmest {{item.name}}?',})export class DeviceItemComponent {  @Input() item!: Item;}@Component({  selector: 'app-lost-item',  template: 'Has anyone seen my {{item.name}}?',})export class LostItemComponent {  @Input() item!: Item;}@Component({  selector: 'app-unknown-item',  template: '{{message}}',})export class UnknownItemComponent {  @Input() item!: Item;  get message() {    return this.item && this.item.name      ? `${this.item.name} is strange and mysterious.`      : 'A mystery wrapped in a fishbowl.';  }}export const ItemSwitchComponents = [  StoutItemComponent,  BestItemComponent,  DeviceItemComponent,  LostItemComponent,  UnknownItemComponent,];
    NgSwitch のアニメーション

スイッチディレクティブは、組み込みのHTML要素とWebコンポーネントでも機能します。 たとえば、<app-best-item> スイッチケースを <div> に置き換えることができます。

src/app/app.component.html

      
<h1>Built-in Directives</h1><h2>Built-in attribute directives</h2><h3 id="ngModel">NgModel (two-way) Binding</h3><fieldset><h4>NgModel examples</h4>  <p>Current item name: {{ currentItem.name }}</p>  <p>    <label for="without">without NgModel:</label>    <input [value]="currentItem.name" (input)="currentItem.name=getValue($event)" id="without">  </p>  <p>    <label for="example-ngModel">[(ngModel)]:</label>    <input [(ngModel)]="currentItem.name" id="example-ngModel">  </p>  <p>    <label for="example-change">(ngModelChange)="...name=$event":</label>    <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">  </p>  <p>    <label for="example-uppercase">(ngModelChange)="setUppercaseName($event)"      <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">    </label>  </p></fieldset><hr><h2 id="ngClass">NgClass Binding</h2><p>currentClasses is {{ currentClasses | json }}</p><div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div><ul>  <li>    <label for="saveable">saveable</label>    <input type="checkbox" [(ngModel)]="canSave" id="saveable">  </li>  <li>    <label for="modified">modified:</label>    <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged" id="modified"></li>  <li>    <label for="special">special: <input type="checkbox" [(ngModel)]="isSpecial" id="special"></label></li></ul><button type="button" (click)="setCurrentClasses()">Refresh currentClasses</button><div [ngClass]="currentClasses">  This div should be {{ canSave ? "": "not"}} saveable,                  {{ isUnchanged ? "unchanged" : "modified" }} and                  {{ isSpecial ? "": "not"}} special after clicking "Refresh".</div><br><br><!-- toggle the "special" class on/off with a property --><div [ngClass]="isSpecial ? 'special' : ''">This div is special</div><div class="helpful study course">Helpful study course</div><div [ngClass]="{'helpful':false, 'study':true, 'course':true}">Study course</div><!-- NgStyle binding --><hr><h3>NgStyle Binding</h3><div [style.font-size]="isSpecial ? 'x-large' : 'smaller'">  This div is x-large or smaller.</div><h4>[ngStyle] binding to currentStyles - CSS property names</h4><p>currentStyles is {{ currentStyles | json }}</p><div [ngStyle]="currentStyles">  This div is initially italic, normal weight, and extra large (24px).</div><br><label for="canSave">italic: <input id="canSave" type="checkbox" [(ngModel)]="canSave"></label> |<label for="isUnchanged">normal: <input id="isUnchanged" type="checkbox" [(ngModel)]="isUnchanged"></label> |<label for="isSpecial">xlarge: <input id="isSpecial" type="checkbox" [(ngModel)]="isSpecial"></label><button type="button" (click)="setCurrentStyles()">Refresh currentStyles</button><br><br><div [ngStyle]="currentStyles">  This div should be {{ canSave ? "italic": "plain"}},                  {{ isUnchanged ? "normal weight" : "bold" }} and,                  {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".</div><hr><h2>Built-in structural directives</h2><h3 id="ngIf">NgIf Binding</h3><div>  <p>If isActive is true, app-item-detail will render: </p>  <app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>  <button type="button" (click)="isActiveToggle()">Toggle app-item-detail</button></div><p>If currentCustomer isn't null, say hello to Laura:</p><div *ngIf="currentCustomer">Hello, {{ currentCustomer.name }}</div><p>nullCustomer is null by default. NgIf guards against null. Give it a value to show it:</p><div *ngIf="nullCustomer">Hello, <span>{{ nullCustomer }}</span></div><button type="button" (click)="giveNullCustomerValue()">Give nullCustomer a value</button><h4>NgIf binding with template (no *)</h4><ng-template [ngIf]="currentItem">Add {{ currentItem.name }} with template</ng-template><hr><h4>Show/hide vs. NgIf</h4><!-- isSpecial is true --><div [class.hidden]="!isSpecial">Show with class</div><div [class.hidden]="isSpecial">Hide with class</div><p>ItemDetail is in the DOM but hidden</p><app-item-detail [class.hidden]="isSpecial"></app-item-detail><div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div><div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div><hr><h2 id="ngFor">NgFor Binding</h2><div class="box">  <div *ngFor="let item of items">{{ item.name }}</div></div><p>*ngFor with ItemDetailComponent element</p><div class="box">  <app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail></div><h4 id="ngFor-index">*ngFor with index</h4><p>with <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; let i=index">{{ i + 1 }} - {{ item.name }}</div></div><p>with <em>comma</em> separator</p><div class="box"> <div *ngFor="let item of items, let i=index">{{ i + 1 }} - {{ item.name }}</div></div><h4 id="ngFor-trackBy">*ngFor trackBy</h4><button type="button" (click)="resetList()">Reset items</button><button type="button" (click)="changeIds()">Change ids</button><button type="button" (click)="clearTrackByCounts()">Clear counts</button><p><em>without</em> trackBy</p><div class="box">  <div #noTrackBy *ngFor="let item of items">({{ item.id }}) {{ item.name }}</div>  <div id="noTrackByCnt" *ngIf="itemsNoTrackByCount" >    Item DOM elements change #{{ itemsNoTrackByCount }} without trackBy  </div></div><p>with trackBy</p><div class="box">  <div #withTrackBy *ngFor="let item of items; trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div>  <div id="withTrackByCnt" *ngIf="itemsWithTrackByCount">    Item DOM elements change #{{ itemsWithTrackByCount }} with trackBy  </div></div><br><br><br><p>with trackBy and <em>semi-colon</em> separator</p><div class="box">  <div *ngFor="let item of items; trackBy: trackByItems">    ({{ item.id }}) {{ item.name }}  </div></div><p>with trackBy and <em>comma</em> separator</p><div class="box">  <div *ngFor="let item of items, trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with trackBy and <em>space</em> separator</p><div class="box">  <div *ngFor="let item of items trackBy: trackByItems">({{ item.id }}) {{ item.name }}</div></div><p>with <em>generic</em> trackById function</p><div class="box">  <div *ngFor="let item of items, trackBy: trackById">({{ item.id }}) {{ item.name }}</div></div><hr><h2>NgSwitch Binding</h2><p>Pick your favorite item</p><div>  <label for="item-{{i}}" *ngFor="let i of items">    <div><input id="item-{{i}}"type="radio" name="items" [(ngModel)]="currentItem" [value]="i">{{ i.name }}    </div>  </label></div><div [ngSwitch]="currentItem.feature">  <app-stout-item    *ngSwitchCase="'stout'"    [item]="currentItem"></app-stout-item>  <app-device-item   *ngSwitchCase="'slim'"     [item]="currentItem"></app-device-item>  <app-lost-item     *ngSwitchCase="'vintage'"  [item]="currentItem"></app-lost-item>  <app-best-item     *ngSwitchCase="'bright'"   [item]="currentItem"></app-best-item>  <div *ngSwitchCase="'bright'">Are you as bright as {{ currentItem.name }}?</div>  <app-unknown-item  *ngSwitchDefault           [item]="currentItem"></app-unknown-item></div>

次のステップ