ngIf
true => Host div will be included in the HTML elements
false => Host div will be excluded in the HTML elements
<div *ngIf="needShow(4)" class="bg-info p-2 mt-1"> Check need to show if pass 4 </div>
<div *ngIf="doNotShow()" class="bg-info p-2 mt-1"> Expect do not show this element </div>
ngSwitch
Same, only matched element will be included in the HTML elements.
However the ngSwitch host element will always be included in HTML element.
<div class="bg-info p-2 mt-1" [ngSwitch]="howManyPeople()">
<span *ngSwitchCase="2">There are two people</span>
<span *ngSwitchCase="5">There are five people</span>
<span *ngSwitchDefault>This is the default</span>
</div>
Need double quote when comparing string
<div class="bg-info p-2 mt-1" [ngSwitch]="whatIsYourName()">
<span *ngSwitchCase="'Anderson'">I know you!!</span>
<span *ngSwitchCase="'QQ'">Hi, nice to meet you</span>
<span *ngSwitchDefault>Hello?</span>
</div>
ngFor
repeats a section of content for each object in an array, providing the template equivalent of a foreach loop.
Template variables: index (zero based number), odd (boolean), even (boolean), first (boolean), last (boolean)
<tr *ngFor="let item of getProducts(); let i = index; let odd = odd; let even = even">
<td>{{item.name}}</td>
<td>{{item.category}}</td>
<td>{{item.price}}</td>
</tr>
由於 ngFor 需要 iterate data, 當 data source 改變的時候, ngFor 需要重新跑一次 data source 會讓效能變差.
為了提升效能, 可以在 component 訂一個 method, 例如 getKey (注意 signature 第一個參數是 index, 第二個參數是 object), 然後在 ngFor 裡面定義 trackBy:getKey, 如此就能讓 ngFor 了解雖然是從 data source 拿到新的物件, 但其實是同一筆資料
- define getKey method
import { ApplicationRef, Component }
from "@angular/core";
import { Model } from "./repository.model";
import { Product } from "./product.model";
@Component({
selector: "app",
templateUrl: "template.html"
})
export class ProductComponent {
model: Model = new Model();
// ...constructor and methods omitted for brevity...
getKey(index: number, product: Product) {
return product.id;
}
}
- 定義 trackBy:getKey
<tr *ngFor="let item of getProducts();let i = index;let odd = odd;let even = even;trackBy:getKey">
<td>{{item.name}}</td>
<td>{{item.category}}</td>
<td>{{item.price}}</td>
</tr>
ngTemplateOutlet
Used to repeat a block of content in a specified location
- Define a template and the content
<ng-template #myTemplate>
<div>Hello</dic>
</ng-template>
- Output the template
<ng-template [ngTemplateOutlet]="myTemplate"></ng-template>
<div>KKKKK</div>
<ng-template [ngTemplateOutlet]="myTemplate"></ng-template>
Provide Context Data Binding
- Define template with context. We defined "text" variable in template, and the value will be the expression result of "title"(Use let- to define a variable)
<ng-template #myTemplate let-text="title">
<h4 class="p-2 bg-success text-white">{{text}}</h4>
</ng-template>
- Use the defined template and provide data for binding
<ng-template [ngTemplateOutlet]="myTemplate" [ngTemplateOutletContext]="{title: 'Header'}"> </ng-template>
Keep in mind
- Expressions need to be idempontent
- Can NOT access objects defined outside of the template's component, and in particular, templates can't access the global namespace.
- Global namespace must be provided by component, acting as on behalf of the template
import { ApplicationRef, Component }
from "@angular/core";
import { Model } from "./repository.model";
import { Product } from "./product.model";
@Component({
selector: "app",
templateUrl: "template.html"
})
export class ProductComponent {
model: Model = new Model();
// ...constructor and methods omitted for brevity...
getNumber(): number {
return Math.floow(1); // The Math can't be accessed by template
}
getKey(index: number, product: Product) {
return product.id;
}
}