| وجه المقارنة المعمارية | إدارة الحالة التقليدية (RxJS & Services) | إدارة الحالة الحديثة بالإشارات (Signals State) |
|---|---|---|
| تتبع التغييرات وتحديث القالب | تتطلب اشتراكات مستمرة واستخدام Async Pipe أو تفعيل Change Detection يدوياً | تحديث تلقائي وفوري وفائق السرعة داخل القوالب دون الحاجة لاشتراكات معقدة |
| استهلاك الموارد والذاكرة | أعلى نسبياً بسبب كثرة الاشتراكات وإدارتها في دورة حياة المكون | منخفض جداً ومحسّن معمارياً لحماية الذاكرة ومنع تسريب البيانات |
| سهولة القراءة والصيانة | معقدة أحياناً في تتبع مسار تدفق البيانات عبر عدة طبقات | نظيفة، مباشرة، وتعتمد على قيم قراءة وكتابة صريحة (Signals & Computed) |
مع توسع نطاق تطبيقات الويب وتعقيد واجهاتها في Angular 22.1، تصبح إدارة الحالة (State Management) هي الركيزة المعمارية الأساسية لضمان استقرار البيانات وتزامنها بين مختلف مكونات التطبيق. الحالة لم تعد مجرد متغيرات عادية داخل الكلاس، بل أصبحت تدفقاً حياً يعكس بيانات المستخدم، وحالة الخادم، وتفاعلات واجهة المستخدم لحظياً، مع الاعتماد الكلي على الإشارات (Signals) والبرمجة التفاعلية النظيفة.
تعتمد معمارية إدارة الحالة في أحدث إصدارات أنجولر على رصد التغييرات على مستوى العنصر بدلاً من فحص شجرة المكونات بالكامل. هذا يضمن أن أي تعديل في الحالة ينعكس فقط على العقدة المرتبطة بها في القالب، مما يرفع الأداء إلى مستويات قياسية.
توجيه المعمارية نحو عزل الحالة عن المكونات الرسومية يتيح إمكانية إعادة استخدام منطق الأعمال، وتسهيل عمليات الاختبار الوحدة (Unit Testing)، وجعل تتبع الأخطاء أمراً يسيراً وواضحاً.
| 1 | import { Injectable, signal, computed } from '@angular/core'; |
| 2 | |
| 3 | export interface UserProfile { |
| 4 | id: number; |
| 5 | name: string; |
| 6 | role: string; |
| 7 | isActive: boolean; |
| 8 | } |
| 9 | |
| 10 | @Injectable({ |
| 11 | providedIn: 'root' |
| 12 | }) |
| 13 | export class UserStateStore { |
| 14 | // الحالة الأساسية الخاصة بالمستخدمين |
| 15 | private usersSignal = signal<UserProfile[]>([ |
| 16 | { id: 1, name: 'أحمد المهندس', role: 'Senior Architect', isActive: true }, |
| 17 | { id: 2, name: 'سارة المبرمجة', role: 'Frontend Developer', isActive: false }, |
| 18 | { id: 3, name: 'محمد الخبير', role: 'Tech Lead', isActive: true } |
| 19 | ]); |
| 20 | |
| 21 | // تعريض الحالة للقراءة فقط للحفاظ على الأمان المعماري |
| 22 | readonly users = this.usersSignal.asReadonly(); |
| 23 | |
| 24 | // حالة محسوبة تستخرج المستخدمين النشطين فقط |
| 25 | readonly activeUsersCount = computed(() => |
| 26 | this.usersSignal().filter(u => u.isActive).length |
| 27 | ); |
| 28 | |
| 29 | // دالة لتعديل الحالة بطريقة آمنة |
| 30 | addUser(newUser: UserProfile) { |
| 31 | this.usersSignal.update(currentUsers => [...currentUsers, newUser]); |
| 32 | } |
| 33 | } |
| 1 | import { Component, inject } from '@angular/core'; |
| 2 | import { CommonModule } from '@angular/common'; |
| 3 | import { UserStateStore } from './user-state.store'; |
| 4 | |
| 5 | @Component({ |
| 6 | selector: 'app-state-management-demo', |
| 7 | standalone: true, |
| 8 | imports: [CommonModule], |
| 9 | template: ` |
| 10 | <div class="master-container"> |
| 11 | <h3>إدارة الحالة الحديثة في Angular 22.1</h3> |
| 12 | <p>عدد الأعضاء النشطين حالياً في النظام: <strong>{{ userStore.activeUsersCount() }}</strong></p> |
| 13 | |
| 14 | <div class="list-container"> |
| 15 | @for (user of userStore.users(); track user.id) { |
| 16 | <div class="user-card" [style.border-color]="user.isActive ? '#34d399' : '#f87171'"> |
| 17 | <p><strong>الاسم:</strong> {{ user.name }}</p> |
| 18 | <p><strong>الدور المعماري:</strong> {{ user.role }}</p> |
| 19 | <p><strong>الحالة:</strong> {{ user.isActive ? 'نشط' : 'غير نشط' }}</p> |
| 20 | </div> |
| 21 | } |
| 22 | </div> |
| 23 | |
| 24 | <button (click)="addNewMember()" class="action-btn">إضافة عضو جديد للحالة</button> |
| 25 | </div> |
| 26 | `, |
| 27 | styles: [` |
| 28 | .master-container { background: #090d16; color: #fff; padding: 24px; border-radius: 12px; } |
| 29 | .list-container { display: flex; flex-direction: column; gap: 12px; margin: 16px 0; } |
| 30 | .user-card { background: #1e293b; padding: 16px; border-radius: 8px; border: 1px solid #334155; } |
| 31 | .user-card p { margin: 4px 0; color: #e2e8f0; } |
| 32 | .action-btn { background: #38bdf8; color: #090d16; border: none; padding: 10px 20px; border-radius: 6px; font-weight: bold; cursor: pointer; } |
| 33 | .action-btn:hover { background: #7dd3fc; } |
| 34 | `] |
| 35 | }) |
| 36 | export class StateManagementDemoComponent { |
| 37 | // حقن المتجر باستخدام الدالة الحديثة inject |
| 38 | readonly userStore = inject(UserStateStore); |
| 39 | |
| 40 | addNewMember() { |
| 41 | this.userStore.addUser({ |
| 42 | id: Date.now(), |
| 43 | name: 'فاطمة المهندسة', |
| 44 | role: 'Angular Core Developer', |
| 45 | isActive: true |
| 46 | }); |
| 47 | } |
| 48 | } |