Dyrektywy strukturalne (te z *, takie jak *ngIf/*ngFor) zmieniają DOM przez . to cukier syntaktyczny — pod maską Angular opakowuje element w i dyrektywa kontroluje czy/jak ten szablon jest renderowany.
Dyrektywy strukturalne (te z *, takie jak *ngIf/*ngFor) zmieniają DOM przez . to cukier syntaktyczny — pod maską Angular opakowuje element w i dyrektywa kontroluje czy/jak ten szablon jest renderowany.
*<ng-template><!-- what you write -->
<p *ngIf="isVisible">Hello</p>
<!-- what Angular actually does -->
<ng-template [ngIf]="isVisible">
<p>Hello</p>
</ng-template>
* mówi Angular: "opakuj ten element w szablon i pozwól dyrektywie zdecydować kiedy go umieścić w DOM." <ng-template> to inertny fragment kodu, który nie jest renderowany, aż dyrektywa go instantyzuje.
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>
Dwa wstrzykiwane elementy są kluczowe: TemplateRef to szablon elementu ("co renderować"), a ViewContainerRef to lokalizacja w DOM ("gdzie"). Dyrektywa wywołuje createEmbeddedView aby dodać element lub clear aby go usunąć.
<!-- 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> }
Ta nowsza składnia jest bardziej czytelna i wydajna, chociaż koncepcja dodawania/usuwania pozostaje taka sama.
Zrozumienie * → <ng-template> rozwinięcia wyjaśnia jak *ngIf/*ngFor dodają i usuwają DOM, i pozwala budować niestandardowe dyrektywy strukturalne (używając TemplateRef + ViewContainerRef) dla zaawansowanej kontroli szablonów — np. renderowanie oparte na uprawnieniach, niestandardowe iteratory lub opóźnione umieszczanie.
Wyjaśnia również dlaczego nie można umieszczać dwóch dyrektyw strukturalnych (*ngIf i *ngFor) na jednym elemencie: każda wymaga własnego opakowania szablonu.