Le direttive strutturali (quelle con *, come *ngIf/) cambiano il DOM . L' è syntactic sugar — sotto il cofano, Angular avvolge l'elemento in un e la direttiva controlla se/come quel template viene renderizzato.
Le direttive strutturali (quelle con *, come *ngIf/) cambiano il DOM . L' è syntactic sugar — sotto il cofano, Angular avvolge l'elemento in un e la direttiva controlla se/come quel template viene renderizzato.
*ngFor*<ng-template><!-- what you write -->
<p *ngIf="isVisible">Hello</p>
<!-- what Angular actually does -->
<ng-template [ngIf]="isVisible">
<p>Hello</p>
</ng-template>
L'* dice ad Angular: "avvolgi questo elemento in un template, e lascia che la direttiva decida quando stamparlo nel DOM." Un <ng-template> è un pezzo di markup inerte che non viene renderizzato finché una direttiva non lo istanzia.
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>
I due pezzi iniettati sono la chiave: TemplateRef è il template dell'elemento (il "cosa renderizzare"), e ViewContainerRef è la posizione nel DOM (il "dove"). La direttiva chiama createEmbeddedView per aggiungere l'elemento o clear per rimuoverlo.
<!-- 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> }
Questa sintassi più recente è più leggibile e performante, anche se il concetto sottostante di aggiunta/rimozione è lo stesso.
Comprendere la desugaring * → <ng-template> demistifica come *ngIf/*ngFor aggiungono e rimuovono il DOM, e ti permette di costruire direttive strutturali personalizzate (usando TemplateRef + ViewContainerRef) per il controllo avanzato dei template — ad esempio rendering basato su permessi, ripetitori personalizzati, o stamping lazy.
Chiarisce anche perché non puoi mettere due direttive strutturali (*ngIf e *ngFor) su un elemento: ognuna ha bisogno del proprio wrapper template.