| معيار المقارنة البرمجية | الطريقة التقليدية (EventEmitter Outputs) | مخرجات الإشارات الحديثة (Signals-based Outputs) |
|---|---|---|
| الاعتمادية الهندسية | تعتمد على فئة EventEmitter التقليدية واستيراد مكتبات متعددة | تعتمد كلياً على دالة output المعيارية الجديدة |
| طريقة إطلاق ونقل الأحداث للأعلى | استخدام دالة .emit() لنقل البيانات | استدعاء المخرج مباشرة كدالة برمجية مثل دالة عادية |
| التوافق مع بنية Signals العامة | منفصلة جزئياً وتتطلب إدارة إضافية لربطها بالحالات التفاعلية | متناغمة تماماً ومصممة خصيصاً لتتكامل مع عمارة الإشارات في أنجولر |
| كود التعريف داخل صنف المكون | notify = new EventEmitter<string>(); | notify = output<string>(); |
نصحح مسار الدرس السابع لنركز بشكل كامل ودقيق على المخرجات باستخدام الإشارات الحديثة (Signals-based Outputs) في إصدار Angular 22.1. في الهندسة البرمجية الحديثة لأنجولر، تم دمج المخرجات (Outputs) بصورة كليّة مع نظام الإشارات لتوفير طريقة أكثر توحيداً وسلاسة لإرسال البيانات والأحداث نحو الأعلى من المكونات الفرعية إلى المكونات الأب، مستغنين عن الأنماط المعقدة القديمة. ومثل الدروس السابقة، سنحافظ على تنوع الأكواد لتشمل ملفات الـ TypeScript، وقوالب الـ HTML، وملفات التنسيق CSS
عند استخدام دالة output<T>() الحديثة، فإنك تُعرّف مخرجاً قادراً على إرسال البيانات للأعلى بأمان تام وبدون الحاجة لإنشاء كائنات EventEmitter ضخمة. يتم إطلاق الحدث عبر استدعاء المخرج كدالة برمجية مباشرة بالقيم المطلوبة (this.myOutput(value)).
تتيح هذه المخرجات للمكونات الأب استقبال الأحداث عبر ربط القوالب بالطريقة المعتادة ((myOutput)="handler($event)")، مع ضمان مطابقة تكامل الأنواع (Type Safety) ومنع الأخطاء البرمجية الخفية في وقت الترجمة.
| 1 | import { Component, output } from '@angular/core'; |
| 2 | |
| 3 | @Component({ |
| 4 | selector: 'app-user-input-form', |
| 5 | standalone: true, |
| 6 | templateUrl: './user-input-form.component.html', |
| 7 | styleUrl: './user-input-form.component.css' |
| 8 | }) |
| 9 | export class UserInputFormComponent { |
| 10 | // تعريف مخرج يعتمد على الإشارات الحديثة لإرسال نص للأعلى |
| 11 | formSubmitted = output<string>(); |
| 12 | |
| 13 | submitData(value: string) { |
| 14 | if (value.trim()) { |
| 15 | // إرسال البيانات عبر استدعاء المخرج كدالة مباشرة |
| 16 | this.formSubmitted(value); |
| 17 | } |
| 18 | } |
| 19 | } |
| 1 | <div class="form-card"> |
| 2 | <h4>نموذج إدخال البيانات الفرعي</h4> |
| 3 | <input #textInput type="text" placeholder="اكتب النص هنا للإرسال للأعلى..." /> |
| 4 | <button (click)="submitData(textInput.value)">إرسال البيانات</button> |
| 5 | </div> |
| 1 | import { Component, signal } from '@angular/core'; |
| 2 | import { UserInputFormComponent } from './user-input-form.component'; |
| 3 | |
| 4 | @Component({ |
| 5 | selector: 'app-workspace-parent', |
| 6 | standalone: true, |
| 7 | imports: [UserInputFormComponent], |
| 8 | template: ` |
| 9 | <div class="workspace"> |
| 10 | <h3>مساحة العمل الرئيسية (الأب)</h3> |
| 11 | <p>الرسالة الواردة من النموذج الفرعي: <strong>{{ latestMessage() }}</strong></p> |
| 12 | |
| 13 | <!-- استقبال الحدث القادم من المكون الفرعي --> |
| 14 | <app-user-input-form (formSubmitted)="handleFormSubmission($event)"></app-user-input-form> |
| 15 | </div> |
| 16 | ` |
| 17 | }) |
| 18 | export class WorkspaceParentComponent { |
| 19 | latestMessage = signal('لم يتم إرسال أي بيانات بعد'); |
| 20 | |
| 21 | handleFormSubmission(message: string) { |
| 22 | // تحديث الإشارة بناءً على البيانات القادمة من المخرجات الحديثة |
| 23 | this.latestMessage.set(message); |
| 24 | } |
| 25 | } |