دایرکتیوها (Directives)
دایرکتیو (Directive) یعنی افزودن رفتار به تگ ها. بنابراین بدون ساخت کامپوننت جدید، همان عنصر کارهای بیشتری انجام می دهد؛ مثل برچسبی که قوانین کلاس را به دفترت اضافه می کند.
معرفی دایرکتیوهای انگولار
دایرکتیوهای ساختاری DOM را کم وزیاد می کنند. اما دایرکتیوهای ویژگی ظاهر و رفتار را تغییر می دهند. ستاره * شُکرِ语 (Sugar) است و به <ng-template> باز می شود.
*ngIf="condition"
*ngFor="let item of items"
@Directive({ selector: '[w3Highlight]' })
<div w3Highlight></div>
دایرکتیوهای پایه: *ngIf و *ngFor
*ngIf نمایش را شرطی می کند. سپس *ngFor روی لیست می چرخد و هر آیتم را نشان می دهد؛ مثل لیست حضور و غیاب.
<p *ngIf="items.length > 0">We have {{ items.length }} items</p>
<li *ngFor="let item of items">{{ item }}</li>
import { bootstrapApplication } from '@angular/platform-browser';
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule],
template: `
<h3>Directives</h3>
<p *ngIf=\"items.length > 0\">We have {{ items.length }} items</p>
<ul>
<li *ngFor=\"let item of items\">{{ item }}</li>
</ul>
<button (click)=\"toggle()\">Toggle Items</button>
`
})
export class App {
show: boolean = true;
get items(): string[] {
return this.show ? ['Angular', 'Components', 'Directives'] : [];
}
toggle(): void {
this.show = !this.show;
}
}
bootstrapApplication(App);
ngIf با else و then
گاهی مسیر جایگزین لازم است. بنابراین با else الگوی پشتیبان بده. همچنین با then/else هر دو شاخه را شفاف کن.
import { bootstrapApplication } from '@angular/platform-browser';
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule],
template: `
<h3>ngIf with else</h3>
<button (click)=\"loggedIn = !loggedIn\">{{ loggedIn ? 'Log out' : 'Log in' }}</button>
<ng-container *ngIf=\"loggedIn; else loggedOut\">
<p>Welcome back, {{ user }}!</p>
</ng-container>
<ng-template #loggedOut>
<p>Please log in to continue.</p>
</ng-template>
<hr>
<h4>ngIf then/else syntax</h4>
<button (click)=\"hasAccess = !hasAccess\">Toggle Access ({{ hasAccess ? 'granted' : 'denied' }})</button>
<ng-container *ngIf=\"hasAccess; then accessTpl; else noAccessTpl\"></ng-container>
<ng-template #accessTpl>
<p style=\"color: seagreen\">Access granted.</p>
</ng-template>
<ng-template #noAccessTpl>
<p style=\"color: crimson\">Access denied.</p>
</ng-template>
`
})
export class App {
loggedIn: boolean = false;
user: string = 'Angular User';
hasAccess: boolean = true;
}
bootstrapApplication(App);
دایرکتیو ویژگی: هایلایت با هاست
دایرکتیو ویژگی DOM را حذف نمی کند. بلکه ظاهر را تغییر می دهد. با @HostBinding و @HostListener واکنش به رویدادها را ساده کن.
import { bootstrapApplication } from '@angular/platform-browser';
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Directive } from '@angular/core';
import { Input } from '@angular/core';
import { HostBinding } from '@angular/core';
import { HostListener } from '@angular/core';
@Directive({
selector: '[w3Highlight]',
standalone: true
})
export class HighlightDirective {
@Input('w3Highlight') highlightColor: string = 'lightyellow';
@HostBinding('style.transition') transition: string = 'background-color 150ms ease-in-out';
@HostBinding('style.backgroundColor') bg: string = '';
@HostListener('mouseenter') onEnter(): void {
this.bg = this.highlightColor;
}
@HostListener('mouseleave') onLeave(): void {
this.bg = '';
}
}
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, HighlightDirective],
styles: [`
.box { padding: 10px; border: 1px dashed #bbb; border-radius: 6px; }
`],
template: `
<h3>Attribute Directive (highlight)</h3>
<p>Hover the first box to see the effect:</p>
<div class=\"box\" [w3Highlight]=\"'lightyellow'\">I get highlighted on hover</div>
<div class=\"box\" style=\"margin-top:8px\">I do not</div>
`
})
export class App {}
bootstrapApplication(App);
گام های تمرینی
- *ngIf را روی وضعیت «لاگین» تست کن.
- با *ngFor یک لیستِ کارها بساز.
- دایرکتیو هایلایت را روی کارت ها اعمال کن.
نکته ها و لینک ها
نکته: روی یک عنصر، دو دایرکتیو ستاره دار نگذار. اگر لازم شد از <ng-container> کمک بگیر.
مطالب مرتبط: دیتا بایندینگ · بایندینگ ویژگی · TrackBy
جمع بندی سریع
- *ngIf نشان می دهد یا پنهان می کند.
- *ngFor روی آرایه تکرار می کند.
- else و then شاخه ها را شفاف می کنند.
- دایرکتیو ویژگی ظاهر را تغییر می دهد.
- برای فهرست های طولانی از TrackBy کمک بگیر.