| وجه المقارنة المعمارية | تمرير القيم للمكونات (Component Inputs) | تمرير القيم للتوجيهات (Directive Inputs) |
|---|---|---|
| طريقة الاستدعاء وربط البيانات | يتم تمرير القيم عبر اسم الخاصية مباشرة داخل وسم المكون (مثل [title]="value") | يتم تمرير القيم عبر اسم التوجيه متبوعاً بالخاصية (مثل [appDirectiveName]="value") |
| الهدف الأساسي من الاستقبال | تغذية المكون ببيانات وهياكل عرض تظهر داخل قالبه الداخلي | تخصيص سلوك أو أنماط أو خصائص العنصر المضيف ديناميكياً |
| الاعتماد على نظام الستريمز والإشارات | مدعوم بالكامل باستخدام دوال الـ `input()` الحديثة | مدعوم بالكامل وباستخدام نفس تقنيات الإشارات (Signal Inputs) في أنجولر |
تمرير القيم والإعدادات للتوجيهات (Passing Inputs to Directives). في الدروس السابقة، بنينا توجيهات ذات سلوك ثابت أو متغيرات داخلية مستقلة. ولكن في تطبيقات الواقع العملي، غالباً ما تحتاج إلى جعل التوجيه قابلاً للتخصيص الكامل من الخارج، بحيث يستقبل معلمات أو خيارات (مثل تحديد لون معين عند التحويم، أو رسالة تنبيه مخصصة) عبر نظام الإشارات الحديث (Input Signals)، مما يرفع من مرونة وقوة التوجيهات البرمجية.
تماماً مثل المكونات، يدعم صنف التوجيه (Directive) استخدام نظام الإشارات الجديد في Angular 22.1. يمكنك تعريف مدخل إلزامي أو اختياري داخل التوجيه باستخدام دالة input() أو input.required<T>().
من أفضل الممارسات عند بناء التوجيهات، هو إعطاء المدخل اسماً مستعاراً يتطابق مع اسم التوجيه نفسه (أو جزء منه)، ليكون استخدام التوجيه في قالب HTML أكثر وضوحاً وسهولة للمطور (مثل [appHighlight]="customColor").
| 1 | import { Directive, ElementRef, HostBinding, HostListener, OnInit, Renderer2, inject, input } from '@angular/core'; |
| 2 | |
| 3 | @Directive({ |
| 4 | selector: '[appAdvancedTooltip]', |
| 5 | standalone: true |
| 6 | }) |
| 7 | export class AdvancedTooltipDirective implements OnInit { |
| 8 | private el = inject(ElementRef); |
| 9 | private renderer = inject(Renderer2); |
| 10 | |
| 11 | // استقبال لون الخلفية المخصص من المكون الأب عبر الإشارات |
| 12 | customBgColor = input<string>('#0ea5e9', { alias: 'tooltipBg' }); |
| 13 | |
| 14 | // استقبال نص الرسالة المراد عرضها كخيار إضافي |
| 15 | tooltipMessage = input.required<string>({ alias: 'tooltipText' }); |
| 16 | |
| 17 | ngOnInit() { |
| 18 | // إعداد النمط المبدئي للعنصر المضيف |
| 19 | this.renderer.setStyle(this.el.nativeElement, 'position', 'relative'); |
| 20 | this.renderer.setStyle(this.el.nativeElement, 'cursor', 'pointer'); |
| 21 | this.renderer.setStyle(this.el.nativeElement, 'borderBottom', '2px dashed #38bdf8'); |
| 22 | } |
| 23 | |
| 24 | // الاستماع لحدث التحويم لعرض رسالة التنبيه أو تعديل الأنماط بناءً على المدخلات |
| 25 | @HostListener('mouseenter') onMouseEnter() { |
| 26 | const bgColor = this.customBgColor(); |
| 27 | const message = this.tooltipMessage(); |
| 28 | |
| 29 | // تطبيق اللون القادم من المدخل ديناميكياً |
| 30 | this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', bgColor); |
| 31 | this.renderer.setStyle(this.el.nativeElement, 'color', '#ffffff'); |
| 32 | |
| 33 | console.log(`[توجيه تفاعلي]: تم تفعيل الرسالة -> ${message}`); |
| 34 | } |
| 35 | |
| 36 | @HostListener('mouseleave') onMouseLeave() { |
| 37 | // إرجاع الأنماط لحالتها الأصلية عند خروج المؤشر |
| 38 | this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'transparent'); |
| 39 | this.renderer.setStyle(this.el.nativeElement, 'color', '#38bdf8'); |
| 40 | } |
| 41 | } |
| 1 | import { Component, signal } from '@angular/core'; |
| 2 | import { AdvancedTooltipDirective } from './advanced-tooltip.directive'; |
| 3 | |
| 4 | @Component({ |
| 5 | selector: 'app-directive-inputs-demo', |
| 6 | standalone: true, |
| 7 | imports: [AdvancedTooltipDirective], |
| 8 | template: ` |
| 9 | <div class="master-container"> |
| 10 | <h3>استعراض تمرير المدخلات والإعدادات للتوجيهات</h3> |
| 11 | <p>قم بالمرور بالمؤشر فوق العناصر أدناه لمشاهدة تأثير القيم الممررة المختلفة:</p> |
| 12 | |
| 13 | <!-- العنصر الأول: تمرير لون أخضر مع رسالة خاصة --> |
| 14 | <div |
| 15 | appAdvancedTooltip |
| 16 | [tooltipBg]="'#10b981'" |
| 17 | [tooltipText]="'هذه رسالة مرتبطة بعملية الحفظ بنجاح'" |
| 18 | class="demo-box"> |
| 19 | مرر مؤشر الفأرة فوق الصندوق الأول (لون أخضر ممرر) |
| 20 | </div> |
| 21 | |
| 22 | <br> |
| 23 | |
| 24 | <!-- العنصر الثاني: تمرير لون أحمر مع رسالة تحذيرية --> |
| 25 | <div |
| 26 | appAdvancedTooltip |
| 27 | [tooltipBg]="'#ef4444'" |
| 28 | [tooltipText]="'تحذير: هذا إجراء خطير يتطلب الحذر'" |
| 29 | class="demo-box"> |
| 30 | مرر مؤشر الفأرة فوق الصندوق الثاني (لون أحمر ممرر) |
| 31 | </div> |
| 32 | </div> |
| 33 | `, |
| 34 | styles: [` |
| 35 | .master-container { background: #090d16; color: #fff; padding: 24px; border-radius: 12px; } |
| 36 | .demo-box { background: #1e293b; color: #38bdf8; padding: 16px; border-radius: 8px; font-weight: bold; border: 1px solid #334155; transition: all 0.3s ease; text-align: center; } |
| 37 | `] |
| 38 | }) |
| 39 | export class DirectiveInputsDemoComponent { |
| 40 | // يمكن إضافة منطق إضافي هنا لتغيير القيم ديناميكياً عبر Signals إذا لزم الأمر |
| 41 | } |