Direktif struktural (yang memiliki *, seperti *ngIf/) mengubah DOM dengan . adalah gula sintaksis — di balik layar, Angular membungkus elemen dalam dan direktif mengontrol kapan/bagaimana template tersebut dirender.
Direktif struktural (yang memiliki *, seperti *ngIf/) mengubah DOM dengan . adalah gula sintaksis — di balik layar, Angular membungkus elemen dalam dan direktif mengontrol kapan/bagaimana template tersebut dirender.
*ngFor*<ng-template><!-- what you write -->
<p *ngIf="isVisible">Hello</p>
<!-- what Angular actually does -->
<ng-template [ngIf]="isVisible">
<p>Hello</p>
</ng-template>
* memberitahu Angular: "bungkus elemen ini dalam template, dan biarkan direktif memutuskan kapan harus memrintahnya ke dalam DOM." <ng-template> adalah bagian markup yang inert dan tidak dirender sampai direktif membuat instansinya.
import { Directive, Input, TemplateRef, ViewContainerRef } from "@angular/core";
@Directive({ selector: "[appUnless]" }) // *appUnless = "the opposite of ngIf"
export class UnlessDirective {
constructor(
private templateRef: TemplateRef<any>, // the wrapped <ng-template>
private viewContainer: ViewContainerRef, // where to render it
) {}
@Input() set appUnless(condition: boolean) {
if (!condition) {
this.viewContainer.createEmbeddedView(this.templateRef); // render it
} else {
this.viewContainer.clear(); // remove it
}
}
}
// usage: <p *appUnless="isHidden">Shown when isHidden is false</p>
Dua bagian yang disuntikkan adalah kunci: TemplateRef adalah template elemen ("apa yang akan dirender"), dan ViewContainerRef adalah lokasi di DOM ("di mana"). Direktif memanggil createEmbeddedView untuk menambah elemen atau clear untuk menghapusnya.
<!-- newer Angular replaces *ngIf/*ngFor with built-in block syntax -->
@if (isVisible) { <p>Hello</p> } @else { <p>Hidden</p> }
@for (item of items; track item.id) { <li>{{ item.name }}</li> }
Sintaks yang lebih baru ini lebih mudah dibaca dan berkinerja lebih baik, meskipun konsep penambahan/penghapusan yang mendasar tetap sama.
Memahami desugaring * → <ng-template> menguraikan bagaimana *ngIf/*ngFor menambah dan menghapus DOM, dan memungkinkan Anda untuk membangun direktif struktural kustom (menggunakan TemplateRef + ViewContainerRef) untuk kontrol template lanjutan — misalnya rendering berbasis izin, pengulangi kustom, atau pencetakan malas.
Juga menjelaskan mengapa Anda tidak dapat meletakkan dua direktif struktural (*ngIf dan *ngFor) pada satu elemen: masing-masing memerlukan wrapper template-nya sendiri.