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

Advanced

Daraja:

Murakkab forma vazifalari: custom UI component'larni formaga ulash, typed forms, dinamik forma generatsiya va performance optimizatsiya.

ControlValueAccessor — custom form control

Senior

Nima bu?

ControlValueAccessor (CVA) — custom component'ni Angular form tizimiga ulash interfeysi. Rating yulduzcha, color picker, rich text editor kabi component'lar [formControl] yoki formControlName bilan ishlashi uchun CVA implement qilinadi.

Metodlar: writeValue, registerOnChange, registerOnTouched, setDisabledState.

Kod misoli

import {
  Component, forwardRef, Input, signal,
} from '@angular/core';
import {
  ControlValueAccessor, NG_VALUE_ACCESSOR,
} from '@angular/forms';

@Component({
  selector: 'app-star-rating',
  standalone: true,
  template: `
    @for (star of [1,2,3,4,5]; track star) {
      <button type="button" (click)="select(star)">
        {{ star <= value() ? '★' : '☆' }}
      </button>
    }
  `,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => StarRatingComponent),
      multi: true,
    },
  ],
})
export class StarRatingComponent implements ControlValueAccessor {
  value = signal(0);
  disabled = signal(false);
  private onChange: (v: number) => void = () => {};
  private onTouched: () => void = () => {};

  writeValue(val: number): void {
    this.value.set(val ?? 0);
  }

  registerOnChange(fn: (v: number) => void): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: () => void): void {
    this.onTouched = fn;
  }

  setDisabledState(isDisabled: boolean): void {
    this.disabled.set(isDisabled);
  }

  select(star: number): void {
    if (this.disabled()) return;
    this.value.set(star);
    this.onChange(star);
    this.onTouched();
  }
}
// Ishlatish
@Component({
  template: `
    <form [formGroup]="form">
      <app-star-rating formControlName="rating" />
      <p>Reyting: {{ form.value.rating }}</p>
    </form>
  `,
})
export class ReviewComponent {
  form = new FormGroup({
    rating: new FormControl(0, Validators.min(1)),
  });
}

Ikkita nozik joy tez-tez interview'da so'raladi. Birinchisi — forwardRef(() => StarRatingComponent): provider massivi klass tanasi (va shu bilan klass nomi) to'liq e'lon qilinmasdan oldin baholanadi, shuning uchun to'g'ridan-to'g'ri StarRatingComponentga havola qilib bo'lmaydi — forwardRef bu havolani lazy qiladi. Ikkinchisi — writeValue tashqaridan (form.setValue(), patchValue(), dastlabki forma yuklanishi) chaqiriladi, ya'ni bu component'ning o'z event handler'i emas. Agar component ChangeDetectionStrategy.OnPush bo'lsa va value signal emas, oddiy field bo'lsa, writeValue ichida view yangilanmasligi mumkin — shuning uchun signal ishlatish yoki writeValue ichida ChangeDetectorRef.markForCheck() chaqirish kerak.

Imtihonda

Savol: CVA'siz custom component formControlName bilan nima qiladi?

Javob: Ishlamaydi — Angular component'ni form control sifatida tan olmaydi. CVA yoki NgModel @Directive kerak.

Savol: forwardRef nega kerak va OnPush bilan writeValue qanday muammo keltirib chiqarishi mumkin?

Javob: forwardRef klass hali e'lon qilinmagan joyda (provider array'ida, klass tanasidan oldin) unga havola berish uchun kerak. OnPushda writeValue component ichidan emas, tashqaridan (setValue/patchValue) chaqirilgani uchun signal ishlatilmasa view yangilanmay qolishi mumkin — signal yoki markForCheck() bilan hal qilinadi.

Yodlash uchun

CVA = writeValue + registerOnChange + registerOnTouched + setDisabledState. NG_VALUE_ACCESSOR provider multi: true. forwardRef — lazy class ref; OnPush'da writeValue uchun signal yoki markForCheck.

Typed Reactive Forms — FormGroup<T> (v14+)

MiddleSenior

Nima bu?

Angular 14+ typed reactive forms — FormGroup, FormControl, FormArray generic tip bilan. form.controls.email — to'g'ridan-to'g'ri FormControlstring``, cast kerak emas. FormBuilder.nonNullable null xavfsizligi beradi.

Kod misoli

interface LoginForm {
  username: FormControl<string>;
  password: FormControl<string>;
  rememberMe: FormControl<boolean>;
}

@Component({
  selector: 'app-typed-login',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form" (ngSubmit)="login()">
      <input formControlName="username" />
      <input formControlName="password" type="password" />
      <label>
        <input formControlName="rememberMe" type="checkbox" /> Eslab qol
      </label>
    </form>
  `,
})
export class TypedLoginComponent {
  private fb = inject(FormBuilder);

  form = this.fb.nonNullable.group<LoginForm>({
    username: this.fb.nonNullable.control('', Validators.required),
    password: this.fb.nonNullable.control('', Validators.required),
    rememberMe: this.fb.nonNullable.control(false),
  });

  login(): void {
    // Tip xavfsiz — string, string, boolean
    const { username, password, rememberMe } = this.form.getRawValue();
    console.log(username.toUpperCase(), rememberMe);
  }

  patchPartial(): void {
    this.form.patchValue({ username: 'admin' }); // faqat username
  }
}

Imtihonda

Savol: nonNullable nima beradi?

Javob: Control qiymati hech qachon null bo'lmaydi — string | null o'rniga string. reset() default qiymatga qaytadi (null emas).

Yodlash uchun

Typed forms: interface + `FormControl`T`` + `fb.nonNullable`. Cast yo'q, autocomplete ishlaydi.

Dynamic form generation

Senior

Nima bu?

Forma struktura JSON/config dan generatsiya qilinadi — admin panel, survey builder, CMS. Har bir field uchun tip, label, validator config beriladi va runtime'da FormGroup + template yaratiladi.

Kod misoli

interface FieldConfig {
  key: string;
  label: string;
  type: 'text' | 'number' | 'select';
  required?: boolean;
  options?: { value: string; label: string }[];
}

const SURVEY_CONFIG: FieldConfig[] = [
  { key: 'fullName', label: 'Ism', type: 'text', required: true },
  { key: 'age', label: 'Yosh', type: 'number' },
  {
    key: 'city', label: 'Shahar', type: 'select',
    options: [
      { value: 'tashkent', label: 'Toshkent' },
      { value: 'samarkand', label: 'Samarqand' },
    ],
  },
];

@Component({
  selector: 'app-dynamic-form',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form" (ngSubmit)="submit()">
      @for (field of config; track field.key) {
        <label>{{ field.label }}</label>
        @switch (field.type) {
          @case ('text') {
            <input [formControlName]="field.key" />
          }
          @case ('number') {
            <input [formControlName]="field.key" type="number" />
          }
          @case ('select') {
            <select [formControlName]="field.key">
              @for (opt of field.options; track opt.value) {
                <option [value]="opt.value">{{ opt.label }}</option>
              }
            </select>
          }
        }
      }
      <button type="submit">Yuborish</button>
    </form>
  `,
})
export class DynamicFormComponent {
  @Input({ required: true }) config!: FieldConfig[];
  form!: FormGroup;

  ngOnInit(): void {
    const group: Record<string, FormControl> = {};
    for (const field of this.config) {
      const validators = field.required ? [Validators.required] : [];
      group[field.key] = new FormControl('', validators);
    }
    this.form = new FormGroup(group);
  }

  submit(): void {
    if (this.form.valid) {
      console.log(this.form.value);
    }
  }
}

Typed reactive forms bilan muammo: FormGroup<T> field'lari compile vaqtida qat'iy interfeys talab qiladi, lekin dynamic form'da field'lar runtime konfiguratsiyadan keladi — oldindan interfeys yozib bo'lmaydi. Shu holat uchun Angular 14+ FormRecord<FormControl<string>> turini taqdim etadi — u Record<string, FormControl>ga o'xshaydi va key'lar runtime'da qo'shilishi/olib tashlanishiga ruxsat beradi, FormGroupdan farqli o'laroq (FormGroup key'lari sxema bo'yicha qat'iy).

Imtihonda

Savol: Dynamic form'da validator qanday qo'shiladi?

Javob: Config'da validator qoidalari saqlanadi (required, min, pattern) va FormControl yaratishda Validators ga map qilinadi. Murakkab validator — config'da funksiya nomi yoki validator registry.

Savol: Dynamic (runtime key'li) formalarda typed forms bilan FormGroup ishlatish mumkinmi?

Javob: Noqulay — FormGroup<T> fixed interfeys talab qiladi. Buning o'rniga FormRecord ishlatiladi — dinamik, oldindan noma'lum key'lar uchun typed control to'plami.

Yodlash uchun

Config array → loop → FormGroup yaratish → @switch template. Formly, ngx-formly kutubxonalari shu pattern'ning tayyor versiyasi. Typed dynamic keys → FormRecord.

Form performance — updateOn, debounce

Senior

Nima bu?

Katta formalarda har keystroke validatsiya va change detection sekinlashtiradi. Optimizatsiya: updateOn: 'blur', valueChanges da debounceTime, OnPush strategy, async validator debounce, emitEvent: false keraksiz event'larni o'chirish.

Kod misoli

@Component({
  selector: 'app-optimized-search',
  standalone: true,
  imports: [ReactiveFormsModule],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <input [formControl]="search" />
    <p>Natijalar: {{ results().length }}</p>
  `,
})
export class OptimizedSearchComponent implements OnInit {
  private api = inject(SearchApiService);
  private destroyRef = inject(DestroyRef);

  search = new FormControl('', { updateOn: 'blur' });
  results = signal<SearchResult[]>([]);

  ngOnInit(): void {
    this.search.valueChanges.pipe(
      debounceTime(300),
      distinctUntilChanged(),
      filter((q): q is string => !!q && q.length >= 2),
      switchMap((q) => this.api.search(q)),
      takeUntilDestroyed(this.destroyRef)
    ).subscribe((data) => this.results.set(data));
  }

  // Ko'p field patch — bitta CD cycle
  bulkUpdate(values: Partial<UserForm>): void {
    this.form.patchValue(values, { emitEvent: false });
    this.form.updateValueAndValidity({ emitEvent: true }); // bir marta
  }

  form = new FormGroup({ /* ... */ });
}

Imtihonda

Savol: emitEvent: false qachon ishlatiladi?

Javob: Ko'p field bir vaqtda yangilanganda har biri uchun valueChanges trigger bo'lmasin. Oxirida bitta updateValueAndValidity({ emitEvent: true }) yetarli.

Yodlash uchun

Performance: updateOn blur + debounceTime + distinctUntilChanged + OnPush + takeUntilDestroyed.
Prev
Validators