| معيار المقارنة البرمجية | المخرجات التقليدية (EventEmitter Outputs) | مخرجات الإشارات الحديثة (Signals-based Outputs) |
|---|---|---|
| الاعتمادية الهندسية | تعتمد على فئة EventEmitter وتتطلب استيراد مزخرفات Outputs | تعتمد كلياً على دالة output المعيارية الجديدة المدمجة بالنظام |
| طريقة إطلاق ونقل الأحداث للأعلى | استخدام دالة .emit() لنقل البيانات وال حمولات | استدعاء المخرج مباشرة كدالة برمجية عادية بالقيمة المطلوبة |
| التوافق مع بنية الإشارات العامة | منفصلة جزئياً وتتطلب إدارة إضافية لربطها بالحالات التفاعلية | متناغمة تماماً ومصممة خصيصاً لتتكامل مع عمارة الإشارات في أنجولر |
| كود التعريف داخل صنف المكون | notify = new EventEmitter<string>(); | notify = output<string>(); |
نصل في هذا الدرس الخامس من الفصل السابع لنغوص في الميزة الثورية المعاصرة في إصدار Angular 22.1، ألا وهي المخرجات الحديثة المعتمدة على الإشارات (Signals-based Outputs). تمثل دالة output() الحديثة التطور الطبيعي لعمارة الإشارات، حيث تدمج عملية إرسال الأحداث والبيانات نحو الأعلى بسلاسة تامة مع نظام الإشارات العام، متخليّة عن الفئات المعقدة القديمة وموفرة واجهة برمجة تطبيقات أنظف وأكثر كفاءة. ومثل الدروس السابقة، سنحافظ على تنوع الأكواد لتشمل ملفات الـ TypeScript، وقوالب الـ HTML، وملفات التنسيق CSS.
عند استخدام دالة output<T>() الحديثة، فإنك تُعرّف مخرجاً قادراً على إرسال البيانات للأعلى بأمان تام وبدون الحاجة لإنشاء كائنات EventEmitter أو استدعاء .emit(). يتم إطلاق الحدث ببساطة عبر استدعاء المخرج كدالة برمجية مباشرة بالقيم المطلوبة (this.myOutput(value)).
تتيح هذه المخرجات للمكونات الأب استقبال الأحداث عبر ربط القوالب بالطريقة المعتادة ((myOutput)="handler($event)")، مع ضمان مطابقة تكامل الأنواع (Type Safety) ومنع الأخطاء البرمجية الخفية أثناء الترجمة.
| 1 | import { Component, output } from '@angular/core'; |
| 2 | |
| 3 | @Component({ |
| 4 | selector: 'app-signal-feedback-form', |
| 5 | standalone: true, |
| 6 | templateUrl: './signal-feedback-form.component.html', |
| 7 | styleUrl: './signal-feedback-form.component.css' |
| 8 | }) |
| 9 | export class SignalFeedbackFormComponent { |
| 10 | // تعريف مخرج يعتمد على الإشارات الحديثة لإرسال نص للأعلى |
| 11 | feedbackSubmitted = output<string>(); |
| 12 | |
| 13 | sendFeedback(text: string) { |
| 14 | if (text.trim()) { |
| 15 | // إرسال البيانات عبر استدعاء المخرج كدالة مباشرة تماماً |
| 16 | this.feedbackSubmitted(text); |
| 17 | } |
| 18 | } |
| 19 | } |
| 1 | <div class="feedback-card"> |
| 2 | <h4>نموذج الملاحظات السريع</h4> |
| 3 | <input #feedbackInput type="text" placeholder="اكتب ملاحظتك هنا للإرسال للأعلى..." /> |
| 4 | <button (click)="sendFeedback(feedbackInput.value)">إرسال الملاحظة</button> |
| 5 | </div> |
| 1 | .feedback-card { |
| 2 | background: #0f172a; |
| 3 | border: 1px solid #334155; |
| 4 | padding: 16px; |
| 5 | border-radius: 8px; |
| 6 | margin-top: 10px; |
| 7 | color: #f8fafc; |
| 8 | } |
| 9 | |
| 10 | .feedback-card input { |
| 11 | padding: 8px 12px; |
| 12 | border: 1px solid #475569; |
| 13 | background: #1e293b; |
| 14 | color: #f8fafc; |
| 15 | border-radius: 4px; |
| 16 | width: 60%; |
| 17 | margin-left: 8px; |
| 18 | } |
| 19 | |
| 20 | .feedback-card button { |
| 21 | padding: 8px 16px; |
| 22 | background: #10b981; |
| 23 | color: white; |
| 24 | border: none; |
| 25 | border-radius: 4px; |
| 26 | cursor: pointer; |
| 27 | font-weight: bold; |
| 28 | } |
| 29 | |
| 30 | .feedback-card button:hover { |
| 31 | background: #059669; |
| 32 | } |
| 1 | import { Component, signal } from '@angular/core'; |
| 2 | import { SignalFeedbackFormComponent } from './signal-feedback-form.component'; |
| 3 | |
| 4 | @Component({ |
| 5 | selector: 'app-admin-control-center', |
| 6 | standalone: true, |
| 7 | imports: [SignalFeedbackFormComponent], |
| 8 | template: ` |
| 9 | <div class="control-center"> |
| 10 | <h3>مركز التحكم الإداري (الأب)</h3> |
| 11 | <p>آخر ملاحظة واردة: <strong>{{ latestFeedback() }}</strong></p> |
| 12 | |
| 13 | <!-- استقبال الحدث القادم من المكون الفرعي بالمخرجات الحديثة --> |
| 14 | <app-signal-feedback-form (feedbackSubmitted)="handleFeedback($event)"></app-signal-feedback-form> |
| 15 | </div> |
| 16 | ` |
| 17 | }) |
| 18 | export class AdminControlCenterComponent { |
| 19 | latestFeedback = signal('لم يتم استلام أي ملاحظات بعد'); |
| 20 | |
| 21 | handleFeedback(content: string) { |
| 22 | // تحديث الإشارة بناءً على البيانات القادمة من المخرجات الحديثة |
| 23 | this.latestFeedback.set(content); |
| 24 | } |
| 25 | } |