Struktūrinės direktyvos (tos su *, pavyzdžiui *ngIf/*ngFor) keičia DOM . yra sintaksinis cukrus — po kapotu Angular apvija elementą ir direktyva valdo, ar/kaip tas šablonas yra renderuojamas.
Struktūrinės direktyvos (tos su *, pavyzdžiui *ngIf/*ngFor) keičia DOM . yra sintaksinis cukrus — po kapotu Angular apvija elementą ir direktyva valdo, ar/kaip tas šablonas yra renderuojamas.
*<ng-template><!-- what you write -->
<p *ngIf="isVisible">Hello</p>
<!-- what Angular actually does -->
<ng-template [ngIf]="isVisible">
<p>Hello</p>
</ng-template>
* nurodo Angular: "apvijk šį elementą šablone ir leisk direktyvai nuspręsti, kada jį įterpti į DOM." <ng-template> yra inertus žymėjimo fragmentas, kuris nerendetuojamas, kol direktyva jo neinstancijuoja.
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>
Du injektuoti fragmentai yra raktingi: TemplateRef yra elemento šablonas ("ką renderuoti"), o ViewContainerRef yra DOM vieta ("kur"). Direktyva iškviečia createEmbeddedView, norėdama pridėti elementą, arba clear jį pašalinti.
<!-- 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> }
Ši naujesnė sintaksė yra labiau skaitoma ir efektyvesnė, nors pagrindinė pridėjimo/pašalinimo koncepcija yra ta pati.
Supratimas apie * → <ng-template> desugaring paaiškina, kaip *ngIf/*ngFor prideda ir pašalina DOM, ir leidžia jums kurti tinklintas struktūrines direktyvas (naudojant TemplateRef + ViewContainerRef) išplėstiniam šablono valdymui — pavyzdžiui, leidimu pagrįstą renderavimą, tinklintas kartotuvus arba lėtą žymėjimą.
Tai taip pat paaiškina, kodėl negalite dėti dviejų struktūrinių direktyvų (*ngIf ir *ngFor) į vieną elementą: kiekviena reikalauja savojo šablono apvalkalo.