Diretivas estruturais (as com *, como *ngIf/*ngFor) alteram o DOM . O é açúcar sintático — nos bastidores, Angular envolve o elemento em um e a diretiva controla se/como esse modelo é renderizado.
Diretivas estruturais (as com *, como *ngIf/*ngFor) alteram o DOM . O é açúcar sintático — nos bastidores, Angular envolve o elemento em um e a diretiva controla se/como esse modelo é renderizado.
*<ng-template><!-- what you write -->
<p *ngIf="isVisible">Hello</p>
<!-- what Angular actually does -->
<ng-template [ngIf]="isVisible">
<p>Hello</p>
</ng-template>
O * diz ao Angular: "envolva este elemento em um modelo e deixe a diretiva decidir quando carimbá-lo no DOM." Um <ng-template> é um pedaço inerte de marcação que não é renderizado até que uma diretiva o instancie.
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>
Os dois elementos injetados são fundamentais: TemplateRef é o modelo do elemento (o "o que renderizar"), e ViewContainerRef é a localização no DOM (o "onde"). A diretiva chama createEmbeddedView para adicionar o elemento ou clear para removê-lo.
<!-- 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 sintaxe mais recente é mais legível e performática, embora o conceito subjacente de adicionar/remover seja o mesmo.
Compreender a desaçucaração * → <ng-template> desmistifica como *ngIf/*ngFor adicionam e removem DOM, e permite construir diretivas estruturais personalizadas (usando TemplateRef + ViewContainerRef) para controle avançado de modelos — por exemplo, renderização baseada em permissões, repetidores personalizados ou carimbagem preguiçosa.
Também esclarece por que você não pode colocar duas diretivas estruturais (*ngIf e *ngFor) em um elemento: cada uma precisa de seu próprio wrapper de modelo.