| طريقة ربط البيانات | اتجاه تدفق وتحديث البيانات | الاستخدام النموذجي في النماذج |
|---|---|---|
| الربط الأحادي للخصائص | من المكون إلى الواجهة فقط | عرض القيم والتحكم في سمات العناصر مثل disabled |
| الربط الأحادي للأحداث | من الواجهة إلى المكون فقط | الاستجابة لضغطات الأزرار أو التقاط أحداث الإدخال يدوياً |
| الربط ثنائي الاتجاه (ngModel) | في الاتجاهين معاً وبشكل تزامني لحظي | ربط حقول النماذج بمتغيرات المكون تلقائياً دون كتابة كود إضافي |
نصل في هذا الدرس إلى حلقة الوصل المتقدمة ضمن الفصل الخامس، وهي الربط ثنائي الاتجاه (Two-Way Data Binding) وتوجيه ngModel في إصدار Angular 22.1. بينما كان الربط الأحادى يعمل في اتجاه واحد (إما من المكون للواجهة أو العكس)، يتيح لك الربط ثنائي الاتجاه مزامنة البيانات لحظياً وفي الوقت الفعلي بين صنف المكون (TypeScript) وحقول الإدخال في الواجهة (HTML)، بحيث يؤدي أي تعديل في الحقل إلى تحديث المتغير تلقائياً، والعكس صحيح.
يُكتب التوجيه ngModel داخل صيغة دمج مميزة تجمع بين الأقواس المربعة والأقواس الهلالية هكذا [(ngModel)]="..."، وهي تدمج بذكاء بين ربط الخصائص [property] وربط الأحداث (event) في سطر برمجى واحد ومختصر.
لكي تعمل خاصية [(ngModel)] بكفاءة في المكونات المستقلة (Standalone Components)، يتطلب الأمر استيراد حزمة FormsModule مباشرة ضمن مصفوفة imports الخاصة بالمكون لضمان تفعيل ميزات النماذج والتحكم فيها.
| 1 | import { Component } from '@angular/core'; |
| 2 | import { FormsModule } from '@angular/forms'; |
| 3 | |
| 4 | @Component({ |
| 5 | selector: 'app-two-way-binding-demo', |
| 6 | standalone: true, |
| 7 | imports: [FormsModule], // ضروري جداً لتفعيل توجيه ngModel في المكونات المستقلة |
| 8 | template: ` |
| 9 | <div class="form-container"> |
| 10 | <h3>نموذج تعديل الملف الشخصي</h3> |
| 11 | |
| 12 | <!-- حقل إدخال مربوط ثنائي الاتجاه بمتغير الاسم --> |
| 13 | <label>اسم المستخدم:</label> |
| 14 | <input type="text" [(ngModel)]="userProfileName" placeholder="أدخل الاسم هنا..."> |
| 15 | |
| 16 | <!-- عرض القيمة المحدثة لحظياً في الواجهة --> |
| 17 | <p>القيمة الحالية للمتغير في المكون: <strong>{{ userProfileName }}</strong></p> |
| 18 | |
| 19 | <button (click)="resetName()">إعادة تعيين الافتراضي</button> |
| 20 | </div> |
| 21 | ` |
| 22 | }) |
| 23 | export class TwoWayBindingDemoComponent { |
| 24 | userProfileName = 'أحمد مطر'; |
| 25 | |
| 26 | resetName() { |
| 27 | this.userProfileName = 'مستخدم جديد'; |
| 28 | } |
| 29 | } |
| 1 | import { Component } from '@angular/core'; |
| 2 | import { FormsModule } from '@angular/forms'; |
| 3 | |
| 4 | @Component({ |
| 5 | selector: 'app-advanced-forms-demo', |
| 6 | standalone: true, |
| 7 | imports: [FormsModule], |
| 8 | template: ` |
| 9 | <div class="settings-panel"> |
| 10 | <!-- 1. ربط قائمة منسدلة (Select) --> |
| 11 | <label>اختر لغة التطبيق المفضلة:</label> |
| 12 | <select [(ngModel)]="selectedLanguage"> |
| 13 | <option value="ar">اللغة العربية</option> |
| 14 | <option value="en">اللغة الإنجليزية</option> |
| 15 | <option value="fr">اللغة الفرنسية</option> |
| 16 | </select> |
| 17 | <p>اللغة المختارة حالياً: {{ selectedLanguage }}</p> |
| 18 | |
| 19 | <!-- 2. ربط صندوق اختيار (Checkbox) --> |
| 20 | <label> |
| 21 | <input type="checkbox" [(ngModel)]="isNotificationsEnabled"> |
| 22 | تفعيل إشعارات البريد الإلكتروني |
| 23 | </label> |
| 24 | <p>حالة الإشعارات: {{ isNotificationsEnabled ? 'مفعلة' : 'معطلة' }}</p> |
| 25 | </div> |
| 26 | ` |
| 27 | }) |
| 28 | export class AdvancedFormsDemoComponent { |
| 29 | selectedLanguage = 'ar'; |
| 30 | isNotificationsEnabled = true; |
| 31 | } |