| وجه المقارنة المعمارية | دالة التحويل toSignal | دالة التحويل toObservable |
|---|---|---|
| اتجاه التحويل والدمج | تحويل تدفق البيانات (Observable) إلى إشارة تفاعلية (Signal) | تحويل إشارة أنگولر (Signal) إلى تدفق زمني (Observable) |
| طريقة التعامل مع الاشتراكات | تدير الاشتراكات تلقائياً خلف الكود دون الحاجة لإلغاء الاشتراك اليدوي | تنشئ تدفقاً تفاعلياً يستجيب لتغيرات الإشارة ويتيح استخدام عوامل RxJS المختلفة |
| مكان الاستخدام الأمثل | داخل سياق الحقن (`Injection Context`) لقراءة بيانات السيرفر أو التدفقات في القوالب | عند الحاجة لتطبيق عمليات ربط معقدة مثل `debounceTime` أو `switchMap` على إشارات محلية |
في معمارية Angular 22.1 الحديثة، بينما تقود الإشارات (Signals) أسلوب إدارة الحالة وتحديث واجهات المستخدم، تظل مكتبة RxJS الأداة الأقوى للتعامل مع التدفقات الزمنية المعقدة واشتراكات الشبكة. الجسر الهندسي المتمثل في دالتي toSignal و toObservable يتيح للمطور دمج عالم التدفقات التقليدية مع عالم الإشارات الحديث بسلاسة تامة، مما يضمن توافقية النظام وتكامل الأكواد البرمجية القديمة والحديثة.
تتيح لك هذه الدالة قراءة مخرجات مكتبة RxJS (مثل طلبات HTTP من HttpClient) واستخدامها مباشرة كإشارة تفاعلية في القوالب دون الحاجة لاستخدام أنبوب async التقليدي، مع إدارة تلقائية لدورة حياة الاشتراك.
عندما تحتاج إلى تنفيذ عمليات معقدة مثل التأخير (debounceTime) أو الدمج (combineLatest) على إشارات أنگولر، فإن تحويل الإشارة إلى تدفق يمنحك القوة الكاملة لمكتبة RxJS بكفاءة عالية.
⚠️ تحذير
تجنب إساءة استخدام دوال الجسر خارج سياق الحقن الصحيح! استخدام toSignal أو toObservable خارج سياق الحقن المعتمد (Injection Context) دون تمرير Injector صريح سيؤدي إلى انهيار التطبيق وأخطاء وقت التشغيل. احرص دائماً على استدعائهما داخل بناء المكون أو الخدمة مباشرة.
| 1 | import { Injectable, signal } from '@angular/core'; |
| 2 | import { toObservable, toSignal } from '@angular/core/rxjs-interop'; |
| 3 | import { delay, of } from 'rxjs'; |
| 4 | |
| 5 | @Injectable({ |
| 6 | providedIn: 'root' |
| 7 | }) |
| 8 | export class BridgeStreamService { |
| 9 | // إشارة محلية للبحث |
| 10 | readonly searchInputSignal = signal<string>(''); |
| 11 | |
| 12 | // تحويل الإشارة إلى Observable لتطبيق عوامل RxJS |
| 13 | readonly searchObservable = toObservable(this.searchInputSignal).pipe( |
| 14 | delay(300) // محاكاة تأخير البحث |
| 15 | ); |
| 16 | |
| 17 | // محاكاة تدفق بيانات قادم من سيرفر وتحويله إلى إشارة |
| 18 | readonly serverDataSignal = toSignal( |
| 19 | of(['بيانات النظام الأولية', 'بيانات الخادم المحدثة']).pipe(delay(1000)), |
| 20 | { initialValue: ['جاري التحميل...'] } |
| 21 | ); |
| 22 | |
| 23 | updateSearch(term: string) { |
| 24 | this.searchInputSignal.set(term); |
| 25 | } |
| 26 | } |
| 1 | <!-- bridge-demo.component.html --> |
| 2 | <div class="bridge-container"> |
| 3 | <h3>لوحة دمج تدفقات RxJS مع الإشارات</h3> |
| 4 | |
| 5 | <div class="stream-section"> |
| 6 | <p><strong>بيانات السيرفر المحولة إلى إشارة:</strong></p> |
| 7 | <ul> |
| 8 | @for (item of streamService.serverDataSignal(); track $index) { |
| 9 | <li>{{ item }}</li> |
| 10 | } |
| 11 | </ul> |
| 12 | </div> |
| 13 | |
| 14 | <div class="stream-section"> |
| 15 | <input |
| 16 | type="text" |
| 17 | (input)="onSearch($event)" |
| 18 | placeholder="اكتب للبحث عبر تدفقات مرنة..." |
| 19 | class="bridge-input" |
| 20 | /> |
| 21 | <p>قيمة إشارة البحث الحالية: <strong>{{ streamService.searchInputSignal() }}</strong></p> |
| 22 | </div> |
| 23 | </div> |