| معيار المقارنة الهندسية | المدخلات التقليدية (@Input) | المخرجات التقليدية (@Output و EventEmitter) |
|---|---|---|
| اتجاه تدفق البيانات | من المكون الأب إلى المكون الفرعي (Top-Down) | من المكون الفرعي إلى المكون الأب (Bottom-Up) |
| الهدف المعماري الأساسي | استقبال وتهيئة البيانات والعروض في الابن | إطلاق الأحداث والإشعارات وتمرير بيانات الإجراءات للأب |
| الآلية البرمجية المستخدمة | استخدام مزخرف الإدخال @Input() وحفظ القيم | استخدام مزخرف الإخراج @Output() مع كلاس EventEmitter ودالة emit() |
لنصل في هذا الدرس الرابع إلى موضوع حاسم وهو إرسال الأحداث والبيانات للأب باستخدام المخرجات التقليدية. في العمارة البرمجية لأنجولر، بينما تُستخدم المدخلات لجلب البيانات من الأعلى للأسفل، تُعتبر المخرجات التي تعتمد على مزخرف @Output وفئة EventEmitter الطريقة الكلاسيكية والموثوقة لإعلام المكون الأب بأي تغير أو إجراء قام به المستخدم داخل المكون الفرعي.
يتيح مزخرف @Output() للمكون الفرعي تصدير أحداث برمجية عبر كائن من فئة EventEmitter. عندما يحدث تفاعل معين (مثل النقر على زر)، يقوم المكون باستدعاء دالة .emit(payload) لتغليف البيانات وإرسالها مباشرة إلى المستمع في المكون الأب.
يستقبل المكون الأب هذه الأحداث باستخدام صيغة الأقواس الهلالية الدائرية (outputEvent)="parentHandler($event)"، مما يتيح التقاط البيانات القادمة ومعالجتها فوراً ضمن سياق الحالة العامة للأب.
| 1 | import { Component, Output, EventEmitter } from '@angular/core'; |
| 2 | |
| 3 | @Component({ |
| 4 | selector: 'app-action-button-box', |
| 5 | standalone: true, |
| 6 | templateUrl: './action-button-box.component.html', |
| 7 | styleUrl: './action-button-box.component.css' |
| 8 | }) |
| 9 | export class ActionButtonBoxComponent { |
| 10 | // تعريف مخرج تقليدي يرسل بيانات من نوع نص للأعلى |
| 11 | dataNotification = new EventEmitter<string>(); |
| 12 | |
| 13 | triggerAction() { |
| 14 | // إطلاق الحدث مع إرسال حمولة البيانات عبر emit |
| 15 | this.dataNotification.emit('تم تنفيذ العملية بنجاح من المكون الفرعي!'); |
| 16 | } |
| 17 | } |
| 1 | <div class="action-box"> |
| 2 | <h4>صندوق الإجراءات الفرعي</h4> |
| 3 | <button (click)="triggerAction()">إرسال إشعار للأب</button> |
| 4 | </div> |
| 1 | .action-box { |
| 2 | background: #1e293b; |
| 3 | color: #f8fafc; |
| 4 | padding: 16px; |
| 5 | border-radius: 8px; |
| 6 | border: 1px solid #475569; |
| 7 | margin-top: 10px; |
| 8 | } |
| 9 | |
| 10 | .action-box button { |
| 11 | background: #0ea5e9; |
| 12 | color: white; |
| 13 | border: none; |
| 14 | padding: 8px 16px; |
| 15 | border-radius: 4px; |
| 16 | cursor: pointer; |
| 17 | font-weight: bold; |
| 18 | } |
| 19 | |
| 20 | .action-box button:hover { |
| 21 | background: #0284c7; |
| 22 | } |
| 1 | import { Component, signal } from '@angular/core'; |
| 2 | import { ActionButtonBoxComponent } from './action-button-box.component'; |
| 3 | |
| 4 | @Component({ |
| 5 | selector: 'app-management-workspace', |
| 6 | standalone: true, |
| 7 | imports: [ActionButtonBoxComponent], |
| 8 | template: ` |
| 9 | <div class="workspace-container"> |
| 10 | <h3>مساحة العمل الإدارية (الأب)</h3> |
| 11 | <p>آخر رسالة مستلمة من الابن: <strong>{{ statusMessage() }}</strong></p> |
| 12 | |
| 13 | <!-- استقبال الحدث عبر الأقواس الهلالية --> |
| 14 | <app-action-button-box (dataNotification)="handleIncomingMessage($event)"> |
| 15 | </app-action-button-box> |
| 16 | </div> |
| 17 | ` |
| 18 | }) |
| 19 | export class ManagementWorkspaceComponent { |
| 20 | statusMessage = signal('في انتظار حدوث أي تفاعل...'); |
| 21 | |
| 22 | handleIncomingMessage(message: string) { |
| 23 | // تحديث الحالة بناءً على البيانات القادمة من المخرج التقليدي |
| 24 | this.statusMessage.set(message); |
| 25 | } |
| 26 | } |