| وجه المقارنة المعمارية | التوفير في الجذر (`providedIn: 'root'`) | التوفير على مستوى المكون (`Component-Level Providers`) |
|---|---|---|
| دورة الحياة (Lifecycle) | تعيش الخدمة طوال فترة تشغيل التطبيق بالكامل (`Singleton`) | تبدأ مع إنشاء المكون وتُدمر تلقائياً فور تدميره (`Destroyed with Component`) |
| مشاركة الحالة (State Sharing) | مشتركة ومرئية لجميع المكونات في التطبيق | معزولة وخاصة حصرياً بنسخة المكون الحالي وشجرته الفرعية فقط |
| الاستخدام النموذجي (Use Cases) | إدارة الحالة العامة، المصادقة، والاتصال بالخوادم (`APIs`) | إدارة حالة النماذج المعقدة، المكونات المؤقتة، أو العناصر القابلة للتكرار |
يُعد توفير الخدمات محلياً داخل المكونات عبر مصفوفة providers أداة هندسية قوية لعزل الحالة (State Isolation). بدلاً من مشاركة نفس النسخة من الخدمة على مستوى التطبيق بالكامل (root)، يتيح لك هذا النمط إنشاء نسخة جديدة ومستقلة تماماً من الخدمة لكل مكون يتم فتحه أو عرضه، مما يمنع تداخل البيانات بين العناصر المتعددة في واجهة المستخدم.
عندما يحتوي صفحة ما على عدة بطاقات أو مكونات متشابهة، فإن توفير الخدمة محلياً يضمن أن كل بطاقة تمتلك عداداً أو بيانات خاصة بها لا تؤثر ولا تتأثر بالبطاقات المجاورة.
بما أن دورة حياة الخدمة مرتبطة ارتباطاً وثيقاً بالمكون، فإن تدمير المكون ينعكس فوراَ على تدمير الخدمة، مما يمنع تسريبات الذاكرة (Memory Leaks) في التطبيقات الضخمة.
⚠️ تحذير
احذر من فقدان مزامنة البيانات بين المكونات! عزل الخدمة محلياً يعني أن المكونات الأخرى لن تتمكن من الوصول إلى نفس الحالة. لا تستخدم هذا النمط إذا كنت بحاجة إلى مشاركة نفس البيانات عبر أجزاء مختلفة من التطبيق.
| 1 | import { Injectable } from '@angular/core'; |
| 2 | |
| 3 | // خدمة محلية بدون providedIn: 'root' لتخصيصها للمكون حصرياً |
| 4 | @Injectable() |
| 5 | export class ItemDetailService { |
| 6 | private status = 'غير نشط'; |
| 7 | |
| 8 | getStatus(): string { |
| 9 | return this.status; |
| 10 | } |
| 11 | |
| 12 | activate(): void { |
| 13 | this.status = 'نشط ومفعل محلياً'; |
| 14 | } |
| 15 | } |
| 1 | import { Component, inject } from '@angular/core'; |
| 2 | import { CommonModule } from '@angular/common'; |
| 3 | import { ItemDetailService } from './item-detail.service'; |
| 4 | |
| 5 | @Component({ |
| 6 | selector: 'app-item-detail', |
| 7 | standalone: true, |
| 8 | imports: [CommonModule], |
| 9 | // توفير الخدمة محلياً لإنشاء نسخة معزولة لكل مكون |
| 10 | providers: [ItemDetailService], |
| 11 | template: ` |
| 12 | <div class="local-container"> |
| 13 | <h3>حقن الخدمات محلياً على مستوى المكونات (Component-Level Providers)</h3> |
| 14 | <p class="status-text">حالة العنصر: <strong>{{ itemService.getStatus() }}</strong></p> |
| 15 | <button (click)="itemService.activate()" class="activate-btn">تفعيل محلياً</button> |
| 16 | </div> |
| 17 | `, |
| 18 | styles: [` |
| 19 | .local-container { background: #090d16; color: #fff; padding: 24px; border-radius: 12px; border: 1px solid #1e293b; margin-top: 10px; } |
| 20 | .status-text { background: #1e293b; padding: 12px; border-radius: 6px; color: #38bdf8; font-weight: bold; } |
| 21 | .activate-btn { background: #10b981; color: #090d16; border: none; padding: 8px 16px; border-radius: 6px; font-weight: bold; cursor: pointer; margin-top: 8px; } |
| 22 | `] |
| 23 | }) |
| 24 | export class ItemDetailComponent { |
| 25 | readonly itemService = inject(ItemDetailService); |
| 26 | } |