Strukturelle Direktiven (die mit *, wie *ngIf/) ändern das DOM durch . Das ist syntaktischer Zucker — unter der Haube wickelt Angular das Element in ein und die Direktive kontrolliert, ob/wie diese Vorlage gerendert wird.
Strukturelle Direktiven (die mit *, wie *ngIf/) ändern das DOM durch . Das ist syntaktischer Zucker — unter der Haube wickelt Angular das Element in ein und die Direktive kontrolliert, ob/wie diese Vorlage gerendert wird.
*ngFor*<ng-template><!-- what you write -->
<p *ngIf="isVisible">Hello</p>
<!-- what Angular actually does -->
<ng-template [ngIf]="isVisible">
<p>Hello</p>
</ng-template>
Das * sagt Angular: "Wickeln Sie dieses Element in eine Vorlage ein, und lassen Sie die Direktive entscheiden, wann sie in das DOM eingefügt wird." Ein <ng-template> ist ein inert Stück Markup, das nicht gerendert wird, bis eine Direktive es instanziiert.
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>
Die zwei eingespritzt Teile sind der Schlüssel: TemplateRef ist die Vorlage des Elements (das "Was gerendert werden soll"), und ViewContainerRef ist die Stelle im DOM (das "Wo"). Die Direktive ruft createEmbeddedView auf, um das Element hinzuzufügen, oder clear um es zu entfernen.
<!-- 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> }
Diese neuere Syntaxe ist lesbarer und performanter, obwohl das zugrunde liegende Hinzufügen/Entfernen-Konzept gleich bleibt.
Das Verständnis des * → <ng-template>-Desugaring demystifiziert, wie *ngIf/*ngFor das DOM hinzufügen und entfernen, und ermöglicht es Ihnen, benutzerdefinierte Strukturelle Direktiven (mit TemplateRef + ViewContainerRef) für erweiterte Template-Kontrolle zu erstellen — z.B. berechtigungsbasiertes Rendering, benutzerdefinierte Repeater oder Lazy Stamping.
Es macht auch klar, warum Sie zwei strukturelle Direktiven (*ngIf und *ngFor) nicht auf einem Element platzieren können: jede benötigt ihren eigenen Template-Wrapper.