Strukturella direktiv (de med *, som *ngIf/*ngFor) ändrar DOM genom att . är syntaktisk socker — under huven slår Angular in elementet i en och direktiven styr om och hur den mallen renderas.
*<ng-template><!-- what you write -->
<p *ngIf="isVisible">Hello</p>
<!-- what Angular actually does -->
<ng-template [ngIf]="isVisible">
<p>Hello</p>
</ng-template>
* säger till Angular: "slå in det här elementet i en mall, och låt direktiven bestämma när det ska stämplas in i DOM." En <ng-template> är en inert bit av markup som inte renderas förrän en direktiv instansierar den.
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>
De två injicerade delarna är nyckeln: TemplateRef är elementets mall ("vad som ska renderas"), och ViewContainerRef är platsen i DOM ("var"). Direktiven anropar createEmbeddedView för att lägga till elementet eller clear för att ta bort det.
<!-- 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> }
Den här nyare syntaxen är mer läsbar och högpresterande, även om det underliggande add/remove-konceptet är detsamma.
Att förstå * → <ng-template> desugaring-en avmystifierar hur *ngIf/*ngFor lägger till och tar bort DOM, och låter dig bygga anpassade strukturella direktiv (med TemplateRef + ViewContainerRef) för avancerad mallkontroll — t.ex. behörighetsbaserad rendering, anpassade repeterare eller lat stämpning.
Det klargör också varför du inte kan placera två strukturella direktiv (*ngIf och *ngFor) på ett element: var och en behöver sin egen mallomslag.