Rakenteelliset direktiivit (ne, joissa on *, kuten *ngIf/) muuttavat DOM:ia . on syntaktista sokeria — sisäisesti Angular kääri elementin -elementtiin ja direktiivi kontrolloi, renderöidäänkö/miten tämä malli renderöidään.
Rakenteelliset direktiivit (ne, joissa on *, kuten *ngIf/) muuttavat DOM:ia . on syntaktista sokeria — sisäisesti Angular kääri elementin -elementtiin ja direktiivi kontrolloi, renderöidäänkö/miten tämä malli renderöidään.
*ngFor*<ng-template><!-- what you write -->
<p *ngIf="isVisible">Hello</p>
<!-- what Angular actually does -->
<ng-template [ngIf]="isVisible">
<p>Hello</p>
</ng-template>
* kertoo Angularille: "kääri tämä elementti malliin ja anna direktiiville päättää, milloin se leimataan DOM:iin." <ng-template> on inaktiivinen merkintöjen pala, jota ei renderöidä, kunnes direktiivi instantioi sen.
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>
Kaksi injektoidua osaa ovat avain: TemplateRef on elementin malli ("mitä renderöidään"), ja ViewContainerRef on sijainti DOM:issa ("mihin"). Direktiivi kutsuu createEmbeddedView -komentoa elementin lisäämiseksi tai clear -komentoa sen poistamiseksi.
<!-- 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> }
Tämä uudempi syntaksi on luettavampi ja tehokkaampi, vaikka taustalla oleva lisä-/poistokäsite on sama.
* → <ng-template> -sokerin poistamisen ymmärtäminen selventää, kuinka *ngIf/*ngFor lisäävät ja poistavat DOM:ia, ja antaa sinulle mahdollisuuden rakentaa mukautettuja rakenteellisia direktiivejä (TemplateRef + ViewContainerRef -opinnolla) edistyneeseen mallinohjaukseen — esim. oikeuksiin perustuva renderöinti, mukautetut toistajat tai laiska leimaus.
Se myös selventää, miksi et voi laittaa kahta rakenteellista direktiiviä (*ngIf ja *ngFor) yhdelle elementille: jokainen tarvitsee oman mallin kääreen.