Las directivas estructurales (las que tienen *, como *ngIf/) cambian el DOM . El es azúcar sintáctico — bajo el capó, Angular envuelve el elemento en un y la directiva controla si/cómo se renderiza esa plantilla.
Las directivas estructurales (las que tienen *, como *ngIf/) cambian el DOM . El es azúcar sintáctico — bajo el capó, Angular envuelve el elemento en un y la directiva controla si/cómo se renderiza esa plantilla.
*ngFor*<ng-template><!-- what you write -->
<p *ngIf="isVisible">Hello</p>
<!-- what Angular actually does -->
<ng-template [ngIf]="isVisible">
<p>Hello</p>
</ng-template>
El * le dice a Angular: "envuelve este elemento en una plantilla, y deja que la directiva decida cuándo seleccionarlo en el DOM." Un <ng-template> es un fragmento de marcado inerte que no se renderiza hasta que una directiva lo instancia.
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>
Los dos fragmentos inyectados son la clave: TemplateRef es la plantilla del elemento (el "qué renderizar"), y ViewContainerRef es la ubicación en el DOM (el "dónde"). La directiva llama a createEmbeddedView para agregar el elemento o clear para eliminarlo.
<!-- 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> }
Esta sintaxis más nueva es más legible y eficiente, aunque el concepto subyacente de agregar/eliminar es el mismo.
Comprender el desazucarado * → <ng-template> desmitifica cómo *ngIf/*ngFor agregan y eliminan el DOM, y te permite crear directivas estructurales personalizadas (usando TemplateRef + ViewContainerRef) para control de plantilla avanzado — por ejemplo, renderizado basado en permisos, repetidores personalizados o marcado perezoso.
También aclara por qué no puedes poner dos directivas estructurales (*ngIf y *ngFor) en un elemento: cada una necesita su propio envoltorio de plantilla.