| ميزة النظام البرمجي | المتغيرات التقليدية (Standard Properties) | الإشارات الحديثة (Signals) |
|---|---|---|
| طريقة تتبع التغييرات | تعتمد على نظام الكشف القديم (Zone.js) لفحص التطبيق بالكامل | تتبع دقيق ولحظي يعتمد على اعتماديات البيانات المباشرة |
| كيفية قراءة القيمة | استدعاء اسم المتغير مباشرة (مثل this.name) | استدعاء الإشارة كدالة (مثل this.name()) |
| كيفية تحديث القيمة | إسناد القيمة الجديدة مباشرة (this.name = 'New') | استخدام دوال مخصصة ومدمجة مثل set أو update |
| الأداء واستهلاك الموارد | أقل كفاءة في التطبيقات الضخمة بسبب عمليات الفحص المتكررة | فائق السرعة ويوفر أداءً مذهلاً ويقلل من إعادة الرسم |
ننتقل في هذا الدرس إلى إحدى أهم وأقوى النماذج البرمجية الحديثة في إصدار Angular 22.1، وهي الإشارات (Signals). تُشكل الإشارات نظاماً جديداً كلياً لإدارة الحالة (State Management) وتتبع التغييرات بكفاءة فائقة. على عكس الآليات التقليدية، توفر الإشارات طريقة دقيقة ومباشرة لإعلام نظام التطبيق بأن قيمة معينة قد تغيرت، مما يتيح لأنجولر تحديث الأجزاء المرتبطة بها في الواجهة فوراً ودون الحاجة لفحص شجرة المكونات بالكامل.
عندما تقوم بقراءة قيمة إشارة داخل قالب الـ HTML أو داخل إشارة محسوبة أخرى، يسجل أنجولر تلقائياً أن هذا العنصر يعتمد على تلك الإشارة. وعند حدوث أي تعديل، يتم تحديث الأجزاء المعتمدة عليها فقط بدلاً من إعادة فحص كل مكونات الصفحة.
لضمان الأمان والوضوح البرمجي، يتم قراءة قيمة الإشارة عن طريق استدعائها كدالة (مثل count())، بينما يتم تعديل قيمتها حصراً عبر الطرق والأساليب البرمجية المدمجة التي توفرها مكتبة أنجولر، مما يمنع التغييرات العشوائية غير المرغوبة.
| 1 | import { Component, signal } from '@angular/core'; |
| 2 | |
| 3 | @Component({ |
| 4 | selector: 'app-signals-intro', |
| 5 | standalone: true, |
| 6 | template: ` |
| 7 | <div class="signal-container"> |
| 8 | <h3>نظام الإشارات الحديث في أنجولر</h3> |
| 9 | |
| 10 | <!-- قراءة قيمة الإشارة عبر استدعائها كدالة --> |
| 11 | <p>النتيجة الحالية للإشارة: <strong>{{ score() }}</strong></p> |
| 12 | |
| 13 | <button (click)="updateScore()">زيادة النقاط</button> |
| 14 | </div> |
| 15 | ` |
| 16 | }) |
| 17 | export class SignalsIntroComponent { |
| 18 | // تعريف إشارة برمجية بقيمة ابتدائية رقمية 100 |
| 19 | score = signal(100); |
| 20 | |
| 21 | updateScore() { |
| 22 | // تحديث قيمة الإشارة باستخدام طريقة الـ update |
| 23 | this.score.update(currentValue => currentValue + 10); |
| 24 | } |
| 25 | } |
| 1 | import { Component, signal } from '@angular/core'; |
| 2 | |
| 3 | @Component({ |
| 4 | selector: 'app-user-signal-profile', |
| 5 | standalone: true, |
| 6 | template: ` |
| 7 | <div class="profile-box"> |
| 8 | <!-- قراءة الإشارة النصية والإشارة المنطقية --> |
| 9 | <h4>اسم المستخدم: {{ username() }}</h4> |
| 10 | <p class="status">الحالة: {{ isLoggedIn() ? 'متصل الآن' : 'غير مسجل الدخول' }}</p> |
| 11 | |
| 12 | <button (click)="toggleLoginStatus()">تبديل حالة الاتصال</button> |
| 13 | <button (click)="changeUsername()">تغيير الاسم البرمجي</button> |
| 14 | </div> |
| 15 | ` |
| 16 | }) |
| 17 | export class UserSignalProfileComponent { |
| 18 | // تعريف إشارات متعددة لأنواع بيانات مختلفة |
| 19 | username = signal('أحمد مطر'); |
| 20 | isLoggedIn = signal(true); |
| 21 | |
| 22 | toggleLoginStatus() { |
| 23 | // استخدام طريقة set لتغيير القيمة المنطقية مباشرة |
| 24 | this.isLoggedIn.set(!this.isLoggedIn()); |
| 25 | } |
| 26 | |
| 27 | changeUsername() { |
| 28 | // تحديث الاسم النصي بقيمة جديدة |
| 29 | this.username.set('سارة أحمد المهندس'); |
| 30 | } |
| 31 | } |