مرجع الديكوريتورات
تُعد الديكوريتورات (Decorators) في أنجولار واحدة من أهم المفاهيم المتقدمة التي تُشكل الأساس البنيوي لهندسة المكونات (Component Architecture) في التطبيقات الحديثة. الديكوريتورات هي عبارة عن تعليقات تعريفية (Metadata Annotations) تُستخدم لتزويد فئات أنجولار (Classes) بالمعلومات التي يحتاجها الإطار (Framework) لتحديد سلوكها ووظائفها ضمن دورة الحياة (Lifecycle) الكاملة للمكون أو الخدمة أو الوحدة.
في أنجولار، تُستخدم الديكوريتورات لتعريف أنواع متعددة من الكيانات مثل @Component، @Directive، @Pipe، @Injectable، و@NgModule، وكل واحدة منها تُضيف طبقة من المنطق البنيوي الذي يتيح لأنجولار إدارة الحالة (State Management) وتدفق البيانات (Data Flow) بشكل منظم وآمن داخل التطبيق.
تُعتبر الديكوريتورات المفتاح لفهم كيفية تفاعل المكونات مع بعضها البعض، وكيف يتم ربط البيانات بين الطبقات المختلفة دون الحاجة إلى تمرير الخصائص بشكل مفرط (Prop Drilling).
سيتعلم القارئ في هذا المرجع كيفية استخدام الديكوريتورات لتكوين مكونات قابلة لإعادة الاستخدام (Reusable Components)، وتحسين أداء التطبيق عبر تقنيات الربط الذكي (Efficient Data Binding) والتعامل مع دورة حياة المكونات (Component Lifecycle) بطريقة احترافية. هذا المرجع يُعد مرجعاً عملياً لتطوير تطبيقات ويب أحادية الصفحة (SPA) حديثة باستخدام أنجولار.
مثال أساسي
typescriptimport { Component, Input } from '@angular/core';
@Component({
selector: 'app-user-card',
template: ` <div class="card"> <h2>{{ name }}</h2> <p>العمر: {{ age }}</p> </div>
`,
styles: [` .card {
padding: 16px;
border-radius: 8px;
background-color: #f5f5f5;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
text-align: center;
}
`]
})
export class UserCardComponent {
@Input() name!: string;
@Input() age!: number;
}
في هذا المثال الأساسي نرى كيف تُستخدم الديكوريتورات لتعريف مكون أنجولار بشكل صريح وواضح. الديكوريتور @Component هو أحد أهم أنواع الديكوريتورات في أنجولار، إذ يُستخدم لتعريف فئة على أنها مكون يمكن لأنجولار التعامل معه كعنصر واجهة مستخدم. الخصائص داخل الديكوريتور مثل selector وtemplate وstyles تُستخدم لتحديد هوية المكون وبنيته البصرية.
الديكوريتور @Input يُمثل قناة لتدفق البيانات من المكون الأب إلى المكون الابن بطريقة آمنة ومنظمة، مما يمنع مشكلة تمرير الخصائص المفرطة (Prop Drilling) ويحافظ على عزل الحالة (State Isolation).
باستخدام هذه البنية، يمكن للمطور بناء واجهات تفاعلية ديناميكية تتفاعل مع المستخدم دون الحاجة إلى تحديثات يدوية متكررة.
من الناحية المفاهيمية، يوضح هذا المثال العلاقة بين إدارة الحالة وتدفق البيانات في أنجولار، حيث يتم تحديد القيم عبر مدخلات Inputs ويتم تحديث الواجهة تلقائياً عند تغير القيم.
هذه البنية تُعد نموذجاً لتصميم مكونات قابلة لإعادة الاستخدام ضمن تطبيقات واسعة النطاق، مع الحفاظ على الأداء عبر تقليل إعادة التصيير (Re-renders) غير الضرورية.
مثال عملي
typescriptimport { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-counter',
template: ` <div class="counter"> <h3>العداد: {{ count }}</h3> <button (click)="increment()">+</button> <button (click)="decrement()">-</button> </div>
`,
styles: [` .counter {
display: flex;
gap: 10px;
align-items: center;
justify-content: center;
}
`]
})
export class CounterComponent {
@Input() count: number = 0;
@Output() countChange = new EventEmitter<number>();
increment() {
this.count++;
this.countChange.emit(this.count);
}
decrement() {
this.count--;
this.countChange.emit(this.count);
}
}
Advanced أنجولار Implementation
typescriptimport { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges } from '@angular/core';
@Component({
selector: 'app-smart-counter',
template: ` <div class="smart-counter"> <h3>قيمة العداد الذكية: {{ value }}</h3> <button (click)="increase()">+</button> <button (click)="decrease()">-</button> </div>
`,
styles: [` .smart-counter {
background-color: #eef2f7;
padding: 16px;
border-radius: 12px;
text-align: center;
}
`]
})
export class SmartCounterComponent implements OnInit, OnChanges {
@Input() value: number = 0;
@Output() valueChange = new EventEmitter<number>();
ngOnInit() {
console.log('SmartCounter initialized with value:', this.value);
}
ngOnChanges(changes: SimpleChanges) {
if (changes['value']) {
console.log('القيمة تغيرت:', changes['value'].currentValue);
}
}
increase() {
this.value++;
this.valueChange.emit(this.value);
}
decrease() {
this.value--;
this.valueChange.emit(this.value);
}
}
أفضل الممارسات في أنجولار للديكوريتورات تتطلب فهماً عميقاً لآلية عمل دورة الحياة وتدفق البيانات. عند استخدام الديكوريتورات، يُنصح بتعريف الخصائص القابلة للإدخال (@Input) فقط عندما تكون هناك حاجة فعلية لاستقبال البيانات من المكونات الأخرى. كما يجب استخدام (@Output) بعناية لإطلاق أحداث (Events) محددة دون الإفراط في التواصل بين المكونات.
من الأخطاء الشائعة التي يجب تجنبها تمرير الحالة عبر طبقات متعددة (Prop Drilling) أو تعديل الحالة مباشرة من مكون خارجي (State Mutation)، إذ يؤدي ذلك إلى صعوبة في تتبع الأخطاء ويقلل من قابلية إعادة الاستخدام.
كما يُنصح باستخدام ChangeDetectionStrategy.OnPush لتحسين الأداء ومنع عمليات إعادة التصيير غير الضرورية.
فيما يتعلق بالأمان، يجب تجنب حقن القيم غير الموثوقة في القوالب وتفعيل Strict Template Type Checking لضمان استقرار التطبيق.
عند تصحيح الأخطاء المتعلقة بالديكوريتورات، يمكن استخدام Angular DevTools لتحليل دورة حياة المكونات ومتابعة الأحداث الناتجة عن @Output.
📊 المرجع الشامل
أنجولار Element/Method | Description | Syntax | Example | Notes |
---|---|---|---|---|
@Component | تعريف فئة كمكون واجهة مستخدم | @Component({...}) | @Component({ selector:'app-demo', template:'...' }) | الديكوريتور الأكثر استخداماً في أنجولار |
@Directive | إنشاء توجيه مخصص للتعامل مع DOM | @Directive({...}) | @Directive({ selector:'[highlight]' }) | يُستخدم لتوسيع سلوك العناصر |
@Pipe | تحويل البيانات داخل القوالب | @Pipe({...}) | @Pipe({name:'capitalize'}) | يُستخدم لتحويل النصوص والقيم |
@NgModule | تعريف وحدة أنجولار | @NgModule({...}) | @NgModule({ declarations:[], imports:[] }) | ينظم المكونات والتوجيهات في وحدات |
@Injectable | جعل فئة قابلة للحقن بالخدمات | @Injectable({...}) | @Injectable({ providedIn:'root' }) | يُستخدم مع خدمات أنجولار |
@Input | تمكين استقبال القيم من المكون الأب | @Input() propName:type | @Input() title:string | يُحافظ على تدفق البيانات من الأعلى للأسفل |
@Output | إطلاق أحداث للمكون الأب | @Output() event=new EventEmitter() | @Output() clicked=new EventEmitter() | يُستخدم للتفاعل بين المكونات |
@HostListener | الاستماع لأحداث DOM | @HostListener('click') handler(){} | @HostListener('window:scroll') onScroll() | يُستخدم لتخصيص سلوك المكون |
@ViewChild | الوصول إلى عنصر أو مكون داخل القالب | @ViewChild(ChildComponent) child!:ChildComponent | يُستخدم للتفاعل مع المكونات الداخلية | |
@ContentChild | الوصول إلى محتوى داخلي مسقَط | @ContentChild(TemplateRef) tpl!:TemplateRef | للتعامل مع المحتوى المسقَط | |
@HostBinding | ربط خاصية DOM بمكون | @HostBinding('class.active') isActive=true | يُستخدم لتحديث الصفات ديناميكياً |
📊 Complete أنجولار Properties Reference
Property | Values | Default | Description | أنجولار Support |
---|---|---|---|---|
selector | string | none | يُحدد اسم العنصر للمكون | جميع الإصدارات |
template | string | none | يُحدد القالب الداخلي | من الإصدار 2+ |
styles | array | string[] | none | يُحدد أنماط CSS المخصصة |
providers | array | [] | قائمة الخدمات المحقونة | من الإصدار 2+ |
inputs | array | [] | خصائص الإدخال المخصصة | من الإصدار 4+ |
outputs | array | [] | خصائص الإخراج المخصصة | من الإصدار 4+ |
animations | array | [] | تعريف حركات المكون | من الإصدار 4+ |
changeDetection | string | 'Default' | تحكم في آلية الكشف عن التغييرات | من الإصدار 5+ |
encapsulation | string | 'Emulated' | نطاق CSS داخل المكونات | من الإصدار 2+ |
standalone | boolean | false | تعريف المكون كمستقل | من الإصدار 14+ |
imports | array | [] | تحديد الوحدات المستوردة | من الإصدار 14+ |
schemas | array | [] | السماح بعناصر مخصصة | من الإصدار 9+ |
الخلاصة والخطوات التالية في أنجولار:
تعلم مرجع الديكوريتورات في أنجولار يُعد خطوة محورية لفهم كيفية بناء تطبيقات عالية الكفاءة والمرونة. يُمكّن هذا الفهم المطورين من تصميم مكونات مستقلة وقابلة لإعادة الاستخدام، مع تحقيق أقصى أداء عبر إدارة ذكية للحالة وتدفق البيانات.
من خلال استيعاب كيفية عمل الديكوريتورات مثل @Component و@NgModule و@Injectable، يصبح المطور قادراً على إنشاء بنية تطبيق متماسكة ومنظمة.
الخطوات التالية المقترحة تشمل دراسة موضوعات متقدمة مثل Dependency Injection، Lifecycle Hooks، وChange Detection Strategy، بالإضافة إلى تحسين الأداء عبر Async Pipes وRxJS.
ينبغي على المطور تطبيق ما تعلمه عملياً من خلال بناء مشاريع واقعية تستخدم هذه الديكوريتورات ضمن تطبيقات حقيقية لإتقان المفهوم بالكامل.
🧠 اختبر معرفتك
اختبر معرفتك
تحدى نفسك مع هذا الاختبار التفاعلي واكتشف مدى فهمك للموضوع
📝 التعليمات
- اقرأ كل سؤال بعناية
- اختر أفضل إجابة لكل سؤال
- يمكنك إعادة الاختبار عدة مرات كما تريد
- سيتم عرض تقدمك في الأعلى