Angular یکی از محبوبترین فریمورکهای جاوا اسکریپت برای توسعه اپلیکیشنهای وب است. اگر به دنبال آموزش Angular هستید، یادگیری مفاهیمی مانند Data Binding و Directives در Angular قدمی اساسی برای تسلط بر این فریمورک محسوب میشود. این مفاهیم به شما کمک میکنند تا رابط کاربری پویا و قابل تعامل ایجاد کنید و منطق اپلیکیشن خود را به بهترین شکل ممکن مدیریت کنید. در این مقاله، این موضوعات را به صورت جامع و از سطح مبتدی تا پیشرفته بررسی خواهیم کرد.
Data Binding در Angular
Data Binding یکی از ویژگیهای برجسته Angular است که امکان برقراری ارتباط بین دادههای موجود در کامپوننت و عناصر HTML را فراهم میکند. این ویژگی به شما اجازه میدهد تا رابط کاربری خود را بر اساس تغییرات دادهها به صورت پویا بهروز کنید. Data Binding در Angular یکی از دلایل اصلی محبوبیت این فریمورک است، چرا که پیچیدگی مدیریت دادهها و نمایش آنها را به شدت کاهش میدهد.
انواع Data Binding
در Angular چهار نوع اصلی Data Binding وجود دارد که هر کدام نقش خاصی در ارتباط بین دادهها و قالب دارند. این چهار نوع عبارتند از:
1. Interpolation ({{}})
Interpolation سادهترین و پرکاربردترین نوع Data Binding است. از این روش برای انتقال دادهها از کامپوننت به قالب HTML استفاده میشود. در این نوع Data Binding، مقادیر متغیرهای تعریف شده در کلاس کامپوننت، در قالب با استفاده از نشانهگذاری {{}} نمایش داده میشوند.
مثال:
<h1>Welcome, {{ username }}!</h1>
در این مثال:
مقدار متغیر username که در فایل کامپوننت تعریف شده است، به صورت خودکار در تگ <h1> جایگذاری و نمایش داده میشود.
هر تغییری در مقدار username در کامپوننت، به صورت پویا در رابط کاربری منعکس خواهد شد.
تعریف یک متغیر در کامپوننت:
export class AppComponent {
username = 'John Doe';
}
نتیجه در رابط کاربری:
Welcome, John Doe!
ویژگیهای Interpolation
فقط خواندنی:
Interpolation تنها امکان انتقال داده از کامپوننت به قالب را فراهم میکند و قابلیت ارسال داده از قالب به کامپوننت وجود ندارد.
مناسب برای محتوای متنی:
این روش اغلب برای نمایش محتوای متنی یا مقدار متغیرها در عناصر HTML استفاده میشود.
قابلیت ترکیب با عبارات ساده جاوا اسکریپت:
میتوانید از عبارات ساده درون {{}} استفاده کنید. به عنوان مثال:
<p>{{ username.toUpperCase() }}</p>
در اینجا مقدار متغیر username به حروف بزرگ تبدیل میشود.
نمیتوان از آن برای تغییر خاصیتهای عناصر استفاده کرد:
اگر بخواهید خاصیتهای HTML (مانند src، class یا style) را تغییر دهید، باید از Property Binding استفاده کنید.
محدودیتها
فقط یکطرفه است: دادهها تنها از کامپوننت به قالب انتقال مییابند و نمیتوان دادهای را از قالب به کامپوننت بازگرداند.
استفاده محدود به متن داخل عناصر HTML: برای سایر ویژگیها مانند استایل یا کلاسها باید از روشهای دیگر Data Binding استفاده کنید.
موارد استفاده عملی از Interpolation
نمایش نام کاربری:
<h2>Hello, {{ user.firstName }} {{ user.lastName }}!</h2>
نمایش محاسبات ریاضی:
<p>Sum: {{ num1 + num2 }}</p>
نمایش وضعیت یا پیامها:
<p>{{ isLoggedIn ? 'Welcome back!' : 'Please log in.' }}</p>
نکتههای بهینهسازی Interpolation
از اجرای عملیات سنگین یا محاسبات پیچیده درون {{}} خودداری کنید؛ زیرا این عملیات ممکن است بر عملکرد اپلیکیشن تأثیر منفی بگذارد. بهتر است این محاسبات را در متدهای کلاس کامپوننت انجام داده و نتیجه را در متغیری ذخیره کنید.
مثال نادرست:
<p>{{ bigArray.filter(item => item.isActive).length }}</p>
مثال بهینه:
export class AppComponent {
activeItemsCount = this.bigArray.filter(item => item.isActive).length;
}
<p>{{ activeItemsCount }}</p>
Property Binding در Angular
Property Binding یکی دیگر از روشهای مهم Data Binding در Angular است که برای تنظیم مقادیر خاصیتهای (properties) عناصر HTML یا کامپوننتها استفاده میشود. این نوع ارتباط، امکان اتصال مستقیم دادههای تعریفشده در کامپوننت به خاصیتهای عناصر HTML را فراهم میکند.
در این روش، از کروشههای [ ] برای اتصال خاصیتهای یک عنصر به متغیرها یا مقادیر تعریفشده در کلاس کامپوننت استفاده میشود. Property Binding یکطرفه است و دادهها تنها از کامپوننت به قالب جریان دارند.
ویژگیهای Property Binding
یکطرفه بودن:
دادهها از کلاس کامپوننت به سمت قالب ارسال میشوند، اما تغییرات در قالب نمیتوانند به کامپوننت بازگردند.
استفاده برای خاصیتهای HTML و DOM:
میتوان از این روش برای تنظیم خاصیتهای استاندارد HTML (مانند src، href، disabled) یا خاصیتهای DOM (مانند innerHTML، textContent) استفاده کرد.
انعطافپذیری در مقایسه با Interpolation
برخلاف Interpolation که برای متن داخلی عناصر استفاده میشود، Property Binding مناسب تنظیم خاصیتهای غیرمتنی است.
مدیریت پویا
Property Binding برای ویژگیهایی که نیاز به تغییرات پویا دارند (مانند تصاویر، لینکها، کلاسها یا مقادیر ورودی) بسیار مفید است.
نحوه استفاده از Property Binding
برای استفاده از Property Binding، خاصیت مورد نظر را در قالب HTML درون [ ] قرار داده و مقدار آن را به یک متغیر یا عبارت در کلاس کامپوننت متصل کنید.
مثال: تنظیم خاصیت src در یک عنصر <img>
HTML:
<img [src]="imageUrl" alt="Dynamic Image">
TypeScript (کامپوننت):
export class AppComponent {
imageUrl = 'https://example.com/image.jpg';
}
در اینجا:
مقدار متغیر imageUrl در کلاس کامپوننت به خاصیت src عنصر <img> متصل شده است.
اگر مقدار imageUrl تغییر کند، تصویر نمایش دادهشده نیز به صورت خودکار بهروز خواهد شد.
موارد استفاده متداول از Property Binding
تنظیم لینکها:
<a [href]="websiteUrl">Visit Website</a>
مدیریت فعال یا غیرفعال بودن عناصر:
<button [disabled]="isButtonDisabled">Click Me</button>
کامپوننت:
export class AppComponent {
isButtonDisabled = true;
}
تغییر پویا کلاسها و استایلها:
<div [class.active]="isActive"></div> <div [style.color]="textColor"></div>
اتصال مقادیر به ورودیها:
<input [value]="username" />
ترکیب با عبارات ساده
در Property Binding میتوانید از عبارات ساده جاوا اسکریپت نیز استفاده کنید.
مثال:
<img [src]="isPremiumUser ? premiumImage : defaultImage" />
کامپوننت:
export class AppComponent {
isPremiumUser = true;
premiumImage = 'https://example.com/premium.jpg';
defaultImage = 'https://example.com/default.jpg';
}
نکات کلیدی در Property Binding
تنظیم خاصیتها نه ویژگیها:
Property Binding در Angular به خاصیتهای DOM مرتبط است، نه ویژگیهای HTML. به عنوان مثال، در یک عنصر <input>، خاصیت value مستقیماً مقدار متن داخل فیلد را مدیریت میکند، اما ویژگی HTML value فقط مقدار اولیه را تنظیم میکند.
بهینهسازی عملکرد:
Property Binding به گونهای طراحی شده است که تنها خاصیتهایی را بهروز کند که تغییر کردهاند. این ویژگی باعث میشود عملکرد بهینهای در اپلیکیشنهای Angular داشته باشید.
کنترل بهتر در مقایسه با Interpolation:
اگر نیاز به مدیریت خاصیتهایی غیر از متن داخلی عناصر دارید (مانند src یا href)، استفاده از Property Binding توصیه میشود.
محدودیتها
یکطرفه بودن:
نمیتوانید از Property Binding برای انتقال داده از قالب به کامپوننت استفاده کنید. برای این کار باید از Two-way Binding یا Event Binding استفاده کنید.
نیاز به خاصیت DOM معتبر:
خاصیت استفادهشده باید در DOM معتبر باشد، در غیر این صورت Angular خطا نمایش میدهد.
تمرین عملی
فرض کنید میخواهید یک اپلیکیشن گالری تصاویر طراحی کنید که تصویر فعلی با کلیک روی دکمه تغییر کند.
HTML:
<img [src]="currentImage" alt="Gallery Image" /> <button (click)="changeImage()">Next Image</button>
کامپوننت:
export class AppComponent {
images = ['image1.jpg', 'image2.jpg', 'image3.jpg'];
currentIndex = 0;
get currentImage() {
return this.images[this.currentIndex];
}
changeImage() {
this.currentIndex = (this.currentIndex + 1) % this.images.length;
}
}
با این روش، هر بار که کاربر روی دکمه کلیک میکند، تصویر جدید نمایش داده میشود
Event Binding در Angular
Event Binding یکی از انواع اصلی Data Binding در Angular است که برای برقراری ارتباط بین تعاملات کاربر و منطق تعریفشده در کامپوننت استفاده میشود. این نوع اتصال به شما اجازه میدهد تا رویدادهایی مانند کلیک، حرکت ماوس، تایپ کاربر، و دیگر رویدادهای DOM را مدیریت کنید.
در Event Binding، از پرانتزهای ( ) برای اتصال رویدادها به متدها یا توابع تعریفشده در کلاس کامپوننت استفاده میشود.
ویژگیهای Event Binding
یکطرفه بودن (از قالب به کامپوننت):
Event Binding دادهها را از تعاملات کاربر در قالب به متدها یا مقادیر داخل کامپوننت ارسال میکند.
تعامل با رویدادهای DOM:
به شما امکان میدهد تا به تمام رویدادهای استاندارد DOM، مانند click، keyup، mouseover، و غیره گوش دهید.
انعطافپذیری بالا:
میتوانید دادههای اضافه را هنگام وقوع رویداد به توابع ارسال کنید.
قابلیت استفاده با Event Modifiers:
Angular اجازه استفاده از اصلاحکنندههای رویداد (Event Modifiers) مانند preventDefault() و stopPropagation() را فراهم میکند.
نحوه استفاده از Event Binding
برای استفاده از Event Binding، یک رویداد DOM را در قالب HTML با استفاده از پرانتز مشخص کرده و آن را به یک متد یا عبارت در کلاس کامپوننت متصل کنید.
مثال: مدیریت رویداد کلیک
HTML:
<button (click)="onClick()">Click Me</button>
TypeScript (کامپوننت):
export class AppComponent {
onClick() {
console.log('Button clicked!');
}
}
در اینجا:
رویداد click دکمه، متد onClick() را در کلاس کامپوننت فراخوانی میکند.
میتوانید کدی برای مدیریت این رویداد در متد onClick قرار دهید.
موارد استفاده متداول از Event Binding
دریافت مقادیر ورودی:
برای دریافت ورودی کاربر از فیلدها:
<input (input)="onInput($event)" />
کامپوننت:
onInput(event: any) {
console.log(event.target.value);
}
مدیریت ماوس و کیبورد:
برای گوش دادن به رویدادهای ماوس یا کیبورد:
<div (mouseover)="onHover()">Hover over me!</div> <input (keyup)="onKeyPress($event)" />
ارسال داده به متدها:
میتوانید دادههای پویا را هنگام وقوع رویداد ارسال کنید:
<button (click)="addItem('Item1')">Add Item</button>
کامپوننت:
addItem(item: string) {
console.log(`Adding ${item}`);
}
Event Binding با استفاده از اصلاحکنندهها
Angular به شما امکان میدهد از اصلاحکنندههای رویداد استفاده کنید تا رفتار پیشفرض مرورگر را تغییر دهید.
جلوگیری از رفتار پیشفرض (preventDefault):
برای مثال، جلوگیری از ارسال فرم:
<form (submit)="onSubmit($event)"> <button type="submit">Submit</button> </form>
کامپوننت:
onSubmit(event: Event) {
event.preventDefault();
console.log('Form submission prevented!');
}
توقف انتشار رویداد (stopPropagation):
میتوانید از انتشار رویداد به عناصر والد جلوگیری کنید:
<div (click)="onParentClick()">Parent Div</div> <button (click)="onChildClick($event)">Child Button</button>
کامپوننت:
onParentClick() {
console.log('Parent clicked!');
}
onChildClick(event: Event) {
event.stopPropagation();
console.log('Child clicked!');
}
ارسال پارامترهای پویا
هنگام استفاده از Event Binding، میتوانید مقادیر پویا را به متد ارسال کنید.
مثال: ارسال مقدار از قالب
HTML:
<button (click)="logMessage('Hello, Angular!')">Log Message</button>
کامپوننت:
logMessage(message: string) {
console.log(message);
}
ترکیب Event Binding با Property Binding
گاهی اوقات ممکن است بخواهید از ترکیب Event Binding و Property Binding استفاده کنید، به ویژه در ورودیهای فرم. Angular برای این منظور از Two-Way Binding استفاده میکند، اما میتوانید از این دو نوع Binding به صورت جداگانه نیز استفاده کنید.
مثال: مدیریت ورودی کاربر
<input [value]="name" (input)="name = $event.target.value" />
<p>Your name: {{ name }}</p>
کامپوننت:
export class AppComponent {
name = '';
}
تمرین عملی
فرض کنید میخواهید دکمهای داشته باشید که تعداد کلیکها را شمارش کند.
HTML:
<button (click)="incrementCounter()">Click Me</button>
<p>You clicked {{ counter }} times!</p>
کامپوننت:
export class AppComponent {
counter = 0;
incrementCounter() {
this.counter++;
}
}
با هر کلیک کاربر، مقدار counter افزایش یافته و مقدار جدید در صفحه نمایش داده میشود.
Two-way Binding در Angular
Two-way Binding در Angular یکی از مهمترین ویژگیهایی است که امکان همگامسازی دادهها بین کامپوننت و قالب را به صورت همزمان فراهم میکند. این روش، ترکیبی از Property Binding و Event Binding است و برای مواردی مانند ورودیهای کاربر در فرمها و فیلدهای تعاملی بسیار مناسب است. با استفاده از این نوع Data Binding، هر تغییری که کاربر در قالب ایجاد میکند، به دادههای کامپوننت اعمال میشود و بالعکس.
ویژگیهای Two-way Binding
همگامسازی دوطرفه:
در این روش، تغییرات در قالب به کامپوننت منتقل میشود و برعکس، تغییرات در کامپوننت نیز بلافاصله در قالب بازتاب پیدا میکند.
ترکیب Property و Event Binding:
Angular به طور خودکار Property Binding (برای نمایش مقدار) و Event Binding (برای گوش دادن به تغییرات) را ترکیب میکند.
بسیار مناسب برای فرمها:
این نوع Data Binding یکی از ابزارهای اصلی در مدیریت فرمها و ورودیهای پیچیده است.
نیاز به FormsModule:
برای استفاده از این قابلیت، ماژول FormsModule باید در اپلیکیشن وارد شود.
استفاده از Two-way Binding در Angular
برای استفاده از Two-way Binding، باید از دستور [(ngModel)] استفاده کنید. این دستور از syntax sugar Angular بهره میبرد و به سادگی، دادهها را بین دو طرف همگامسازی میکند.
مثال ساده:
<input [(ngModel)]="userInput" placeholder="Enter your name">
<p>Your input: {{ userInput }}</p>
کامپوننت:
export class AppComponent {
userInput: string = '';
}
در این مثال:
مقدار userInput همواره با مقدار فیلد ورودی (input) هماهنگ است.
تغییر مقدار فیلد ورودی، متغیر userInput در کامپوننت را بهروز میکند.
هر تغییری در userInput به طور خودکار در قالب نمایش داده میشود.
مراحل راهاندازی Two-way Binding
وارد کردن FormsModule:
ابتدا باید FormsModule را به ماژول Angular اضافه کنید.
app.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule // FormsModule اضافه شده است
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
استفاده از [(ngModel)]:
از این دستور در تگهای ورودی (input)، انتخابگرها (select)، و دیگر عناصر تعاملی HTML استفاده کنید.
مثالهای پیشرفته از Two-way Binding
1. استفاده در فیلتر لیست:
فرض کنید یک لیست فیلترپذیر دارید.
HTML:
<input [(ngModel)]="filterText" placeholder="Filter items">
<ul>
<li *ngFor="let item of items | filter:filterText">{{ item }}</li>
</ul>
کامپوننت:
export class AppComponent {
filterText: string = '';
items = ['Angular', 'React', 'Vue', 'Svelte'];
}
2. مدیریت فرمهای ساده:
HTML:
<form>
<label>
Name:
<input [(ngModel)]="formData.name" name="name">
</label>
<label>
Email:
<input [(ngModel)]="formData.email" name="email">
</label>
<button (click)="submitForm()">Submit</button>
</form>
کامپوننت:
export class AppComponent {
formData = { name: '', email: '' };
submitForm() {
console.log('Form Data:', this.formData);
}
}
ترکیب Two-way Binding با دیگر ویژگیهای Angular
استفاده همراه با اعتبارسنجی فرمها:
میتوانید از Two-way Binding برای مدیریت خطاهای اعتبارسنجی استفاده کنید.
HTML:
<form #form="ngForm">
<input [(ngModel)]="email" name="email" required email>
<div *ngIf="form.controls.email?.invalid && form.controls.email?.touched">
Invalid email address!
</div>
</form>
مزایا و معایب Two-way Binding
مزایا:
سادگی و خوانایی:
کدهایی که از Two-way Binding استفاده میکنند، معمولاً کوتاهتر و سادهتر هستند.
همگامسازی خودکار:
دادهها و UI بهصورت خودکار همگام میشوند.
مناسب برای فرمها:
این روش برای فرمهای پیچیده بسیار کاربردی است.
معایب:
ممکن است کارایی را تحت تأثیر قرار دهد:
اگر بهینهسازی مناسبی انجام نشود، تغییرات زیاد در دادهها میتواند باعث کاهش کارایی شود.
پیچیدگی در پروژههای بزرگ:
در اپلیکیشنهای پیچیده، استفاده زیاد از Two-way Binding ممکن است باعث دشواری در مدیریت دادهها شود.
تمرین عملی
مثال: ورودی و خروجی دما
ایجاد یک اپلیکیشن ساده که دمای ورودی کاربر را به فارنهایت و سلسیوس تبدیل میکند.
HTML:
<label>
Temperature in Celsius:
<input [(ngModel)]="temperature" placeholder="Enter temperature">
</label>
<p>Temperature in Fahrenheit: {{ (temperature * 9/5) + 32 }}</p>
کامپوننت:
export class AppComponent {
temperature: number = 0;
}
Directives در Angular
Directives یکی از اصلیترین ابزارهای Angular هستند که امکان تغییر یا گسترش رفتار عناصر HTML را فراهم میکنند. این قابلیت به توسعهدهندگان اجازه میدهد تا تعاملات پیچیدهای را در قالبهای HTML ایجاد کنند. Directives میتوانند ظاهر یا رفتار عناصر را کنترل کرده و ساختار DOM را به صورت پویا تغییر دهند.
در Angular، سه نوع Directive وجود دارد:
Structural Directives
Attribute Directives
Directives سفارشی
در این بخش، بر روی Structural Directives تمرکز میکنیم که ساختار DOM را تغییر میدهند.
1. Structural Directives
Structural Directives، ساختار DOM را با افزودن یا حذف عناصر تغییر میدهند. این Directives با استفاده از پیشوند * در قالبها تعریف میشوند و مستقیماً بر روی المانهای HTML اعمال میشوند.
الف) *ngIf
این Directive برای نمایش یا پنهان کردن عناصر بر اساس یک شرط منطقی استفاده میشود.
مثال:
<p *ngIf="isLoggedIn">Welcome back!</p> <p *ngIf="!isLoggedIn">Please log in.</p>
کامپوننت:
export class AppComponent {
isLoggedIn: boolean = true;
}
اگر مقدار isLoggedIn برابر true باشد، پیام “Welcome back!” نمایش داده میشود.
در غیر این صورت، پیام “Please log in.” نمایش داده میشود.
ویژگیها:
عنصر مربوطه تنها زمانی در DOM ایجاد میشود که شرط true باشد.
برای بهینهسازی، میتوانید از else نیز استفاده کنید:
<p *ngIf="isLoggedIn; else loginPrompt">Welcome back!</p> <ng-template #loginPrompt> <p>Please log in.</p> </ng-template>
ب) *ngFor
این Directive برای تکرار عناصر بر اساس یک آرایه یا لیستی از دادهها استفاده میشود.
مثال:
<ul>
<li *ngFor="let item of items">{{ item }}</li>
</ul>
کامپوننت:
export class AppComponent {
items = ['Angular', 'React', 'Vue'];
}
هر عنصر li برای هر آیتم در آرایه items ایجاد میشود.
ویژگیها:
میتوانید از اندیس هر آیتم استفاده کنید:
<ul>
<li *ngFor="let item of items; index as i">{{ i + 1 }}. {{ item }}</li>
</ul>
خروجی:
1. Angular 2. React 3. Vue
سایر متغیرهای محلی:
first → بررسی میکند آیا آیتم اولین عنصر است.
last → بررسی میکند آیا آیتم آخرین عنصر است.
even و odd → بررسی میکنند آیا اندیس آیتم زوج یا فرد است.
<ul>
<li *ngFor="let item of items; first as isFirst">
<span *ngIf="isFirst">🌟</span> {{ item }}
</li>
</ul>
ج) *ngSwitch
این Directive برای مدیریت نمایش عناصر بر اساس یک مقدار یا شرط استفاده میشود.
مثال:
<div [ngSwitch]="role"> <p *ngSwitchCase="'admin'">Admin Panel</p> <p *ngSwitchCase="'user'">User Dashboard</p> <p *ngSwitchDefault>Guest View</p> </div>
کامپوننت:
export class AppComponent {
role: string = 'user';
}
اگر مقدار role برابر ‘admin’ باشد، پیام “Admin Panel” نمایش داده میشود.
اگر مقدار role برابر ‘user’ باشد، پیام “User Dashboard” نمایش داده میشود.
در غیر این صورت، پیام “Guest View” نمایش داده میشود.
ویژگیها:
[ngSwitch]: مقدار شرط اصلی را تعیین میکند.
ngSwitchCase: برای هر شرط خاص تعریف میشود.
ngSwitchDefault: مقدار پیشفرض را در صورت عدم تطابق سایر شرایط نمایش میدهد.
نکات مهم درباره Structural Directives
*پیشوند :
تمامی Structural Directives با یک ستاره (*) شروع میشوند. این نشاندهنده این است که Directive به کل عنصر HTML اعمال شده و ساختار DOM را تغییر میدهد.
ng-template:
Angular از یک تگ خاص به نام <ng-template> برای مدیریت محتوای مربوط به Structural Directives استفاده میکند. این تگ مستقیماً در خروجی HTML دیده نمیشود اما برای پردازش داخلی استفاده میشود.
مثال:
<ng-template [ngIf]="isLoggedIn"> <p>Welcome back!</p> </ng-template>
مدیریت کارایی:
Structural Directives تنها در زمانی که شرط آنها برقرار باشد، عنصر را در DOM ایجاد میکنند. این ویژگی باعث بهبود کارایی و کاهش مصرف منابع میشود.
تمرین عملی
ایجاد لیست پویا
ایجاد یک لیست از وظایف روزانه که میتوان آنها را اضافه یا حذف کرد.
HTML:
<div>
<input [(ngModel)]="newTask" placeholder="Add a new task">
<button (click)="addTask()">Add</button>
</div>
<ul>
<li *ngFor="let task of tasks; let i = index">
{{ task }}
<button (click)="removeTask(i)">Remove</button>
</li>
</ul>
کامپوننت:
export class AppComponent {
tasks: string[] = [];
newTask: string = '';
addTask() {
if (this.newTask.trim()) {
this.tasks.push(this.newTask);
this.newTask = '';
}
}
removeTask(index: number) {
this.tasks.splice(index, 1);
}
}
Attribute Directives در Angular
Attribute Directives برای تغییر ظاهر یا رفتار عناصر HTML به صورت پویا استفاده میشوند. برخلاف Structural Directives که ساختار DOM را تغییر میدهند، Attribute Directives فقط ویژگیهای یک عنصر موجود را تغییر میدهند. این تغییرات میتوانند شامل استایلها، کلاسها یا تعاملات دیگر باشند.
الف) [ngStyle]
[ngStyle] یک Attribute Directive است که برای تغییر سبکهای CSS یک عنصر HTML به صورت پویا استفاده میشود. این Directive به توسعهدهندگان اجازه میدهد که مقادیر استایل را بر اساس متغیرهای کامپوننت تعیین کنند.
مثال:
<p [ngStyle]="{'color': isActive ? 'green' : 'red', 'font-size': '20px'}">
Status: {{ isActive ? 'Active' : 'Inactive' }}
</p>
کامپوننت:
export class AppComponent {
isActive: boolean = true;
}
توضیحات:
اگر مقدار isActive true باشد، متن به رنگ سبز نمایش داده میشود.
اگر مقدار isActive false باشد، متن به رنگ قرمز نمایش داده میشود.
میتوانید چندین ویژگی CSS را همزمان تنظیم کنید.
ویژگیها:
مناسب برای تغییرات پیچیده در استایلها.
استفاده از آبجکتهای جاوااسکریپت برای تعیین مقادیر.
ب) [ngClass]
[ngClass] برای افزودن یا حذف کلاسهای CSS به صورت پویا استفاده میشود. این Directive امکان کنترل دقیق کلاسها را بر اساس شرایط منطقی فراهم میکند.
مثال:
<p [ngClass]="{'active': isActive, 'inactive': !isActive}">
This is a dynamic class example.
</p>
CSS:
.active {
color: green;
font-weight: bold;
}
.inactive {
color: gray;
text-decoration: line-through;
}
کامپوننت:
export class AppComponent {
isActive: boolean = true;
}
توضیحات:
اگر isActive true باشد، کلاس active به عنصر اعمال میشود.
اگر isActive false باشد، کلاس inactive اعمال میشود.
ویژگیها:
میتوانید یک آرایه از کلاسها یا یک آبجکت شرطی ارائه دهید.
مناسب برای تغییرات پیچیده در کلاسبندی CSS.
پیشرفته: میتوانید ترکیبی از کلاسها را به صورت پویا اعمال کنید:
<p [ngClass]="['class1', isActive ? 'class2' : 'class3']"> Example with multiple classes. </p>
ساخت Directiveهای سفارشی
گاهی اوقات، نیاز به رفتارهای خاصی دارید که در Directives پیشفرض Angular موجود نیستند. در این مواقع، میتوانید Directives سفارشی ایجاد کنید.
مراحل ساخت Directive سفارشی
1. ایجاد Directive
برای ایجاد یک Directive سفارشی، از دستور زیر استفاده کنید:
ng generate directive customDirective
این دستور یک فایل جدید با نام custom-directive.directive.ts ایجاد میکند.
2. پیادهسازی Logic
برای تغییر رفتار یا استایل یک عنصر HTML، از کلاس Directive استفاده میکنیم. این کلاس میتواند با استفاده از تزریق وابستگیها به عنصر دسترسی داشته باشد.
مثال: ایجاد یک Directive برای برجسته کردن متن
import { Directive, ElementRef, Renderer2 } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {
// تغییر رنگ پسزمینه عنصر
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'yellow');
}
}
توضیحات:
ElementRef: دسترسی مستقیم به عنصر HTML.
Renderer2: ابزار ایمن برای دستکاری DOM (بدون وابستگی به مرورگر خاص).
3. استفاده از Directive
پس از تعریف Directive، میتوانید از آن در قالب HTML استفاده کنید.
مثال:
<p appHighlight> This text is highlighted with a custom directive. </p>
ویژگیهای پیشرفته Directives سفارشی
تعریف ویژگیهای پویا: میتوانید مقدار خاصیتها را به Directive پاس دهید.
@Directive({
selector: '[appDynamicHighlight]'
})
export class DynamicHighlightDirective {
@Input('appDynamicHighlight') highlightColor: string = 'yellow';
constructor(private el: ElementRef, private renderer: Renderer2) {}
ngOnInit() {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', this.highlightColor);
}
}
استفاده:
<p [appDynamicHighlight]="'lightblue'">This text has a dynamic highlight color.</p>
گوش دادن به رویدادها: میتوانید با رویدادهای ماوس یا کلیک تعامل داشته باشید.
@Directive({
selector: '[appHoverHighlight]'
})
export class HoverHighlightDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {}
@HostListener('mouseenter') onMouseEnter() {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'lightblue');
}
@HostListener('mouseleave') onMouseLeave() {
this.renderer.removeStyle(this.el.nativeElement, 'backgroundColor');
}
}
استفاده:
<p appHoverHighlight>Hover over this text to see the effect.</p>
نتیجهگیری
Data Binding و Directives در Angular از مهمترین مفاهیم این فریمورک قدرتمند هستند که امکان ارتباط پویا بین دادهها و رابط کاربری را فراهم میکنند. با استفاده از انواع Data Binding مانند Interpolation، Property Binding، Event Binding و Two-way Binding، میتوانید بهراحتی دادههای خود را به قالب متصل کرده و تعاملات کاربر را مدیریت کنید. همچنین، Directives به شما این امکان را میدهند که ظاهر و رفتار عناصر HTML را تغییر داده و ساختار DOM را به صورت پویا کنترل کنید.
درک عمیق Data Binding و Directives در Angular به شما کمک میکند تا اپلیکیشنهایی کارآمدتر، پویاتر و قابل مدیریتتر بسازید. برای یادگیری بیشتر، پیشنهاد میکنیم مستندات رسمی Angular و دورههای آنلاین معتبر را بررسی کنید.
