A strukturális direktívák (azok, amelyek *-al rendelkeznek, mint *ngIf/) a DOM-ot módosítják. A szintaktikus cukor — a háttérben az Angular egy -ba csomagol be az elemet, és a direktíva szabályozza, hogy a sablont mikor/hogyan kell renderelni.
A strukturális direktívák (azok, amelyek *-al rendelkeznek, mint *ngIf/) a DOM-ot módosítják. A szintaktikus cukor — a háttérben az Angular egy -ba csomagol be az elemet, és a direktíva szabályozza, hogy a sablont mikor/hogyan kell renderelni.
*ngFor*<ng-template><!-- what you write -->
<p *ngIf="isVisible">Hello</p>
<!-- what Angular actually does -->
<ng-template [ngIf]="isVisible">
<p>Hello</p>
</ng-template>
A * azt mondja az Angular-nak: "csomagold be ezt az elemet egy sablonba, és hagyd, hogy a direktíva döntsön róla, mikor helyezze azt be a DOM-ba." Az <ng-template> egy inert markup-blokk, amely nem kerül renderelésre, amíg egy direktíva nem példányosítja.
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>
A két injektált elem a kulcs: TemplateRef az elem sablona (az "mit kell renderelni"), és ViewContainerRef a helye a DOM-ban (az "hol"). A direktíva meghívja a createEmbeddedView fügvényt az elem hozzáadásához vagy a clear fügvényt az eltávolításához.
<!-- 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> }
Ez az újabb szintaxis olvashatóbb és teljesítményesebb, bár az alapvető add/remove koncepció ugyanaz.
A * → <ng-template> desugaring megértése tisztázza, hogy a *ngIf/*ngFor hogyan adja hozzá és távolítja el a DOM-ot, és lehetővé teszi az egyedi strukturális direktívák felépítését (a TemplateRef + ViewContainerRef felhasználásával) fejlett sablonvezérléshez — például engedélyen alapuló renderelés, egyedi ismétlők, vagy lusta bélyegzés.
Egyúttal tisztázza, hogy miért nem lehet két strukturális direktívát (*ngIf és *ngFor) egy elemre helyezni: mindegyikhez saját sablon burkolata szükséges.