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.ts
で true
に設定されています。
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
を使用
メソッドを使用して
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; }}
テンプレートで、要素のクラスを設定するために、
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
を使用して、コンポーネントの状態に基づいて、複数のインラインスタイルを同時に設定します。
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; }}
要素のスタイルを設定するには、
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
ディレクティブを使用して、データプロパティを表示し、ユーザーが変更を加えたときにそのプロパティを更新します。
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; }}
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
ディレクティブは、ControlValueAccessor によってサポートされている要素で機能します。
Angularは、すべての基本的なHTMLフォーム要素に対して 値アクセサー を提供します。
詳細については、フォーム を参照してください。
[(ngModel)]
を非フォームの組み込み要素またはサードパーティのカスタムコンポーネントに適用するには、値アクセサーを作成する必要があります。
詳細については、DefaultValueAccessor に関するAPIドキュメントを参照してください。
HELPFUL: Angularコンポーネントを作成する際、Angularの 双方向バインディング構文 に従って値とイベントプロパティに名前を付ければ、値アクセサーや NgModel
は必要ありません。
組み込み構造ディレクティブ
構造ディレクティブは、HTMLレイアウトを担当します。 これらは、通常、付加されているホスト要素を追加、削除、および操作することによって、DOMの構造を形成または再形成します。
このセクションでは、最も一般的な組み込み構造ディレクティブを紹介します。
一般的な組み込み構造ディレクティブ | 詳細 |
---|---|
NgIf |
テンプレートからサブビューを条件付きで作成または破棄します。 |
NgFor |
リスト内の各アイテムに対してノードを繰り返します。 |
NgSwitch |
代替ビューを切り替えるディレクティブのセットです。 |
詳細については、構造ディレクティブ を参照してください。
NgIf
を使用して要素を追加または削除する
ホスト要素に NgIf
ディレクティブを適用することによって、要素を追加または削除します。
NgIf
が false
の場合、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
式が真の値を返す場合、NgIf
は ItemDetailComponent
をDOMに追加します。
式が偽の場合、NgIf
は ItemDetailComponent
をDOMから削除し、コンポーネントとそのすべてのサブコンポーネントを破棄します。
NgIf
と NgIfElse
の詳細については、NgIf API ドキュメント を参照してください。
null
に対する保護
デフォルトでは、NgIf
は null
値にバインドされた要素の表示を防ぎます。
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>
を表示しません。
この例では、nullCustomer
は null
であるため、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
を使用するには、以下を行う必要があります。
- Angularが単一のアイテムをどのようにレンダリングするかを決定するHTMLブロックを定義します。
- アイテムを一覧表示するには、
*ngFor
にlet 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>
テンプレート入力変数の詳細については、構造ディレクティブの省略記号 を参照してください。
*ngFor
の index
を取得する
テンプレート入力変数で *ngFor
の index
を取得し、テンプレート内で使用します。
*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
を使用してアイテムを追跡する
アプリケーションがサーバーに送信する呼び出しの数を減らすには、アイテムリストへの変更を追跡します。
*ngFor
の trackBy
プロパティを使用すると、Angularは、アイテムリスト全体をリロードするのではなく、変更されたアイテムのみを変更して再レンダリングできます。
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; }}
省略記号式で、
trackBy
をtrackByItems()
メソッドに設定します。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
の変更のみが要素の置き換えをトリガーします。
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>
FormsModule
からngModel
ディレクティブをインポートします。FormsModule
を、関連するAngularモジュールのインポートセクションに追加します。<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>
NgSwitch
を使用してケースを切り替える
JavaScriptの switch
ステートメントと同様に、NgSwitch
は、スイッチ条件に基づいて、いくつかの可能な要素の中から1つの要素を表示します。
Angularは、選択された要素のみをDOMに配置します。
NgSwitch
は、3つのディレクティブのセットです。
NgSwitch ディレクティブ |
詳細 |
---|---|
NgSwitch |
仲間のディレクティブの動作を変更する属性ディレクティブ。 |
NgSwitchCase |
バインドされた値がスイッチ値と等しい場合に、その要素を DOM に追加し、バインドされた値がスイッチ値と等しくない場合に、その要素を DOM から削除する構造ディレクティブ。 |
NgSwitchDefault |
選択された NgSwitchCase がない場合に、その要素を DOM に追加する構造ディレクティブ。 |
ディレクティブを使用するには、NgSwitch
、NgSwitchCase
、および 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
を使用
<div>
などの要素に、[ngSwitch]
を追加し、スイッチ値を返す式(例:feature
)にバインドします。 この例のfeature
値は文字列ですが、スイッチ値は任意の型にできます。ケースの要素に、
*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>
親コンポーネントで、
[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; }}
各子コンポーネントで、親コンポーネントの
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,];
スイッチディレクティブは、組み込みの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>