IslomDevIslomDev
Booster
Imtihon
Booster
Imtihon
  • Angular Intervyu Tayyorgarlik
  • JavaScript / TypeScript

    • JavaScript / TypeScript
    • Asoslar (JavaScript)
    • Asinxronlik
    • Prototip va OOP
    • TypeScript
    • Performance
  • Algoritmlash

    • Algoritmlash
    • Murakkablik tahlili
    • Ma'lumot tuzilmalari
    • Qidiruv va Saralash
    • Algoritmik paradigmalar
    • Amaliy masalalar
  • Angular — Boshlang'ich

    • Angular — Boshlang'ich
    • Component
    • Template
    • Change Detection
    • Advanced Component
  • Angular — Service va DI

    • Angular — Service va DI
    • Service asoslari
    • HTTP
    • Hierarchical DI
    • Advanced DI
    • State management (service)
  • Angular — Versiyalar

    • Angular — Versiyalar
    • Angular 12–13
    • Angular 14
    • Angular 15
    • Angular 16
    • Angular 17
    • Angular 18+
  • Angular — Directive

    • Angular — Directive
    • Built-in Directives
    • Custom Attribute Directive
    • Custom Structural Directive
    • Advanced
  • Angular — RxJS

    • Angular — RxJS
    • Observable asoslari
    • Asosiy operatorlar
    • Higher-order operatorlar
    • Combination operatorlar
    • Subject turlari
    • Xato va xotira
    • Advanced
  • Angular — Pipe

    • Angular — Pipe
    • Built-in Pipes
    • Custom Pipe
    • Performance
  • Angular — Forms

    • Angular — Forms
    • Template-driven Forms
    • Reactive Forms
    • Validators
    • Advanced
  • Angular — NgModule

    • Angular — NgModule
    • NgModule asoslari
    • Module arxitekturasi
    • Lazy Loading
    • Standalone vs NgModule
  • Angular — Sintaksis va Clean Code

    • Angular — Sintaksis va Clean Code
    • Template sintaksisi
    • Angular 17+ yangi sintaksis
    • Komponent arxitekturasi
    • Performance pattern'lar
    • SOLID va Clean Code
    • Testing

Reactive Forms

Daraja:

Reactive Forms — form holati TypeScript kodida FormControl, FormGroup, FormArray orqali boshqariladi. Murakkab validatsiya, dinamik field'lar va test qilish uchun qulayroq.

ReactiveFormsModule import

Middle

Nima bu?

Reactive formlar uchun ReactiveFormsModule import qilinadi. Bu formControl, formGroup, formArray directive'larini va FormBuilder ni faollashtiradi. Template-driven FormsModule dan alohida.

Kod misoli

import { Component } from '@angular/core';
import { ReactiveFormsModule, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-search',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    <input [formControl]="query" placeholder="Qidirish..." />
    @if (query.invalid && query.touched) {
      <span>Kamida 2 belgi kiriting</span>
    }
  `,
})
export class SearchComponent {
  query = new FormControl('', { validators: [Validators.minLength(2)] });
}

Imtihonda

Savol: Reactive formda name attribute kerakmi?

Javob: Yo'q. [formControl] yoki formControlName TypeScript ob'ektiga bog'langan — DOM name shart emas.

Yodlash uchun

Reactive = `ReactiveFormsModule`. Logic TypeScript'da, template faqat bog'lash.

FormControl — bitta field

Middle

Nima bu?

FormControl — bitta input maydonining holati va qiymati. value, valid, dirty, touched, errors property'lari bor. Template'da [formControl]="ctrl" yoki FormGroup ichida formControlName="field".

Kod misoli

import { FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-email-input',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    <input [formControl]="email" type="email" />
    <p>Qiymat: {{ email.value }}</p>
    <p>Valid: {{ email.valid }}</p>
    <p>Xato: {{ email.errors | json }}</p>
    <button (click)="email.setValue('test@mail.com')">To'ldirish</button>
    <button (click)="email.reset()">Tozalash</button>
  `,
})
export class EmailInputComponent {
  email = new FormControl('', {
    validators: [Validators.required, Validators.email],
    nonNullable: true, // reset() bo'sh string qaytaradi, null emas
  });
}

Imtihonda

Savol: setValue va patchValue farqi FormControl'da?

Javob: FormControl uchun ikkalasi ham deyarli bir xil — to'liq qiymat o'rnatadi. Farq FormGroup da ko'rinadi: setValue barcha field talab qiladi, patchValue qisman yangilaydi.

Yodlash uchun

FormControl = 1 field. `setValue()`, `reset()`, `valueChanges` Observable.

FormGroup — fields to'plami

Middle

Nima bu?

FormGroup — bir nechta FormControl (yoki ichki FormGroup/FormArray) ni birlashtiradi. [formGroup]="form" va formControlName="fieldName" bilan template bog'lanadi. Butun form valid/dirty holati group darajasida ham mavjud.

Kod misoli

@Component({
  selector: 'app-user-form',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form" (ngSubmit)="save()">
      <input formControlName="firstName" />
      <input formControlName="lastName" />
      <input formControlName="email" type="email" />
      <button type="submit" [disabled]="form.invalid">Saqlash</button>
    </form>
  `,
})
export class UserFormComponent {
  form = new FormGroup({
    firstName: new FormControl('', Validators.required),
    lastName: new FormControl('', Validators.required),
    email: new FormControl('', [Validators.required, Validators.email]),
  });

  save(): void {
    if (this.form.valid) {
      console.log(this.form.value);
      // { firstName: '...', lastName: '...', email: '...' }
    }
  }

  // Typed access
  get emailControl(): FormControl {
    return this.form.get('email') as FormControl;
  }
}

Imtihonda

Savol: form.get('email') nima qaytaradi?

Javob: AbstractControl | null. FormControl sifatida ishlatish uchun cast yoki typed FormGroup (v14+) kerak.

Yodlash uchun

FormGroup = ob'ekt struktura. `[formGroup]` + `formControlName`. `form.value` — barcha field qiymatlari.

FormArray — dinamik fields

Middle

Nima bu?

FormArray — dinamik ro'yxat field'lar (telefon raqamlari, mahsulot qatorlari). FormControl yoki FormGroup elementlarini saqlaydi. push(), removeAt(), at(index) metodlari bilan boshqariladi.

Kod misoli

@Component({
  selector: 'app-phone-list',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    <div [formGroup]="form">
      <div formArrayName="phones">
        @for (phone of phones.controls; track $index) {
          <div>
            <input [formControlName]="$index" placeholder="+998..." />
            <button type="button" (click)="removePhone($index)">O'chirish</button>
          </div>
        }
      </div>
      <button type="button" (click)="addPhone()">Raqam qo'shish</button>
    </div>
  `,
})
export class PhoneListComponent {
  form = new FormGroup({
    phones: new FormArray<FormControl<string>>([
      new FormControl('', { nonNullable: true, validators: Validators.required }),
    ]),
  });

  get phones(): FormArray {
    return this.form.get('phones') as FormArray;
  }

  addPhone(): void {
    this.phones.push(
      new FormControl('', { nonNullable: true, validators: Validators.required })
    );
  }

  removePhone(index: number): void {
    this.phones.removeAt(index);
  }
}

Imtihonda

Savol: FormArray template'da qanday iterate qilinadi?

Javob: formArrayName="phones" + @for (ctrl of phones.controls; track $index) + [formControlName]="$index". Index track muhim — DOM qayta yaratilishini oldini oladi.

Yodlash uchun

FormArray = dinamik ro'yxat. `controls` array, `push/removeAt/at`. Nested: FormArray ichida FormGroup ham bo'lishi mumkin.

FormBuilder — qisqa yaratish usuli

Middle

Nima bu?

FormBuilder (fb) — FormGroup, FormControl va FormArray yaratishni soddalashtiradi. [value, validators] tuple sintaksisi qisqaroq kod beradi. nonNullable varianti Angular 14+ typed forms bilan ishlaydi.

Kod misoli

import { FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-product-form',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form" (ngSubmit)="submit()">
      <input formControlName="name" />
      <input formControlName="price" type="number" />
      <div formArrayName="tags">
        @for (tag of tags.controls; track $index) {
          <input [formControlName]="$index" />
        }
      </div>
      <button type="submit">Saqlash</button>
    </form>
  `,
})
export class ProductFormComponent {
  private fb = inject(FormBuilder);

  form = this.fb.nonNullable.group({
    name: ['', [Validators.required, Validators.minLength(2)]],
    price: [0, [Validators.required, Validators.min(0)]],
    tags: this.fb.nonNullable.array<string>(['']),
  });

  get tags(): FormArray {
    return this.form.controls.tags;
  }

  submit(): void {
    console.log(this.form.getRawValue()); // disabled field'lar ham
  }
}

Imtihonda

Savol: getRawValue() va value farqi?

Javob: value — disabled control'larni o'z ichiga olmaydi. getRawValue() — barcha control qiymatlarini qaytaradi (disabled ham).

Yodlash uchun

FormBuilder: `fb.group({ field: ['', Validators.required] })`. `nonNullable` — null emas, default qiymat.

updateOn: 'blur' | 'submit' | 'change'

Middle

Nima bu?

Validatorlar va holat yangilanishi qachon trigger bo'lishini belgilaydi:

  • change (default) — har keystroke'da
  • blur — field fokus yo'qotganda
  • submit — faqat form submit bo'lganda

Performance va UX uchun muhim — kam validatsiya = tezroq form.

Kod misoli

@Component({
  selector: 'app-heavy-form',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
      <input formControlName="username" />
      <!-- blur'da validate -->
      <input formControlName="search" />
      <!-- faqat submit'da validate -->
      <input formControlName="notes" />
      <button type="submit">Yuborish</button>
    </form>
  `,
})
export class HeavyFormComponent {
  private fb = inject(FormBuilder);

  form = new FormGroup({
    username: new FormControl('', {
      validators: Validators.required,
      updateOn: 'blur',
    }),
    search: new FormControl('', {
      validators: [Validators.minLength(3)],
      updateOn: 'change', // default — har harfda
    }),
    notes: new FormControl('', {
      validators: Validators.maxLength(500),
      updateOn: 'submit',
    }),
  });

  // Butun form uchun
  formGroup = this.fb.group(
    { title: ['', Validators.required] },
    { updateOn: 'blur' }
  );

  onSubmit(): void {
    this.form.markAllAsTouched();
    if (this.form.valid) { /* ... */ }
  }
}

Imtihonda

Savol: Async validator bilan updateOn: 'change' muammosi?

Javob: Har keystroke'da HTTP so'rov ketadi — performance muammo. Async validator uchun updateOn: 'blur' yoki debounce qo'yish kerak.

Yodlash uchun

Tez-tez validatsiya = change. UX yaxshi = blur. Eng kam = submit. Async validator → blur/debounce.
Prev
Template-driven Forms
Next
Validators