| العنصر البرمجي الأساسي | المسؤولية المعمارية المباشرة | مثال عملي على الاستخدام |
|---|---|---|
| `FormControl` | إدارة قيمة وحالة تدقيق (Validation) لحقل إدخال واحد فقط | متابعة وفحص قيمة حقل البريد الإلكتروني أو كلمة المرور |
| `FormGroup` | تجميع عدة كائنات `FormControl` أو `FormGroup` فرعية في كائن حالة موحد | إدارة بيانات نموذج التسجيل الكامل الذي يحتوي على عدة حقول مترابطة |
| `FormBuilder` | خدمة حقن لتسهيل وتجريد عملية إنشاء الهياكل المعقدة بكود أقل | إنشاء كائنات النماذج بسرعة واختصار عبر أساليب برمجية مساعدة (`this.fb.group(...)`) |
تُمثل اللبنات الثلاث الأساسية (FormControl, FormGroup, FormBuilder) العمود الفقري لبناء أي نظام نماذج تفاعلي عالي الأداء. يمثل FormControl أصغر وحدة تحكم فردية (قيمة وحالة حقل واحد)، بينما يجمع FormGroup مجموعة من هذه الحقول تحت سقف واحد، ويأتي FormBuilder كأداة هندسية مساعدة لاختصار وترتيب كتابة الكود البرمجي بأسلوب نظيف ومنظم.
يمكنك بناء النماذج بإنشاء كائنات صريحة عبر new FormControl('') و new FormGroup({...})، وهو الأسلوب الكلاسيكي المباشر الذي يمنحك فهماً دقيقاً لكيفية عمل الحالة تحت الغطاء.
في التطبيقات الكبيرة، يُفضل استخدام خدمة FormBuilder لتقليل حجم الكود المكتوب (Boilerplate Code) وجعل ملفات الـ TypeScript أكثر قابلية للقراءة والصيانة.
| 1 | import { Component, OnInit } from '@angular/core'; |
| 2 | import { CommonModule } from '@angular/common'; |
| 3 | import { ReactiveFormsModule, FormControl, FormGroup, FormBuilder, Validators } from '@angular/forms'; |
| 4 | |
| 5 | @Component({ |
| 6 | selector: 'app-form-builder-core', |
| 7 | standalone: true, |
| 8 | imports: [CommonModule, ReactiveFormsModule], |
| 9 | template: ` |
| 10 | <div class="core-form-card"> |
| 11 | <h3>هندسة بناء النماذج عبر FormGroup و FormBuilder</h3> |
| 12 | |
| 13 | <form [formGroup]="productForm" (ngSubmit)="onSubmitCoreForm()"> |
| 14 | |
| 15 | <!-- حقل منشأ عبر FormControl بشكل مباشر --> |
| 16 | <div class="field-row"> |
| 17 | <label>اسم المنتج (عبر FormControl مباشر):</label> |
| 18 | <input type="text" [formControl]="productNameControl" class="input-box" /> |
| 19 | </div> |
| 20 | |
| 21 | <!-- مجموعة منشأة عبر FormBuilder --> |
| 22 | <div formGroupGroupName class="sub-group-box"> |
| 23 | <h4>تفاصيل التسعير والمخزون (عبر FormBuilder)</h4> |
| 24 | <div class="field-row"> |
| 25 | <input type="number" formControlName="price" placeholder="السعر..." class="input-box" /> |
| 26 | <input type="number" formControlName="stock" placeholder="المخزون..." class="input-box" /> |
| 27 | </div> |
| 28 | </div> |
| 29 | |
| 30 | <!-- زر الإرسال --> |
| 31 | <button type="submit" [disabled]="productForm.invalid" class="submit-btn"> |
| 32 | حفظ وتأكيد بيانات المنتج |
| 33 | </button> |
| 34 | </form> |
| 35 | </div> |
| 36 | `, |
| 37 | styles: [` |
| 38 | .core-form-card { background: #090d16; color: #fff; padding: 24px; border-radius: 12px; border: 1px solid #1e293b; } |
| 39 | .field-row { margin-bottom: 16px; display: flex; flex-direction: column; gap: 6px; } |
| 40 | .input-box { background: #1e293b; border: 1px solid #334155; padding: 10px; border-radius: 6px; color: #fff; } |
| 41 | .sub-group-box { background: #1e293b; border: 1px solid #334155; padding: 16px; border-radius: 8px; margin-bottom: 16px; } |
| 42 | .sub-group-box h4 { margin-top: 0; color: #38bdf8; font-size: 14px; margin-bottom: 12px; } |
| 43 | .submit-btn { background: #10b981; color: #090d16; border: none; padding: 10px 20px; border-radius: 6px; font-weight: bold; cursor: pointer; width: 100%; } |
| 44 | .submit-btn:disabled { background: #475569; cursor: not-allowed; color: #94a3b8; } |
| 45 | `] |
| 46 | }) |
| 47 | export class FormBuilderCoreComponent implements OnInit { |
| 48 | // طريقة 1: إنشاء FormControl مستقل بذاته |
| 49 | productNameControl = new FormControl('', [Validators.required, Validators.minLength(2)]); |
| 50 | |
| 51 | // طريقة 2: نموذج رئيسي يجمع الكائنات |
| 52 | productForm!: FormGroup; |
| 53 | |
| 54 | constructor(private fb: FormBuilder) {} |
| 55 | |
| 56 | ngOnInit(): void { |
| 57 | // دمج الـ FormControl المستقل مع مجموعة منشأة بـ FormBuilder داخل FormGroup رئيسي |
| 58 | this.productForm = this.fb.group({ |
| 59 | productName: this.productNameControl, |
| 60 | formGroupGroupName: this.fb.group({ |
| 61 | price: [0, [Validators.required, Validators.min(1)]], |
| 62 | stock: [0, [Validators.required, Validators.min(0)]] |
| 63 | }) |
| 64 | }); |
| 65 | } |
| 66 | |
| 67 | onSubmitCoreForm() { |
| 68 | if (this.productForm.valid) { |
| 69 | console.log('البيانات الهيكلية للنموذج:', this.productForm.value); |
| 70 | } |
| 71 | } |
| 72 | } |