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

Change Detection

### Default strategy — butun tree tekshirish
JuniorMiddle

Nima bu?

Default change detection strategiyasi (ChangeDetectionStrategy.Default) har bir asinxron hodisa (click, HTTP, setTimeout, Zone.js event) dan keyin komponent daraxtining butun qismini tekshiradi. Har qanday o'zgarish topilsa template qayta render qilinadi. Sodda, lekin katta ilovalarda ortiqcha ishlash yukini keltirishi mumkin.

Kod misoli

import { Component, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-default-cd',
  standalone: true,
  // Default — ko'rsatmasa ham shu
  changeDetection: ChangeDetectionStrategy.Default,
  template: `
    <p>Counter: {{ counter }}</p>
    <p>User: {{ user.name }}</p>
    <button type="button" (click)="increment()">+1</button>
    <button type="button" (click)="mutateUser()">Mutate</button>
  `,
})
export class DefaultCdComponent {
  counter = 0;
  user = { name: 'Ali' };

  increment(): void {
    this.counter++;
  }

  mutateUser(): void {
    // Default CD: reference o'zgarmasa ham zone event CD ni ishga tushiradi
    this.user.name = 'Vali';
  }
}

Imtihonda

  • Change detection qachon trigger bo'ladi?
  • Default strategiya nima uchun "xavfsiz" hisoblanadi?
  • Zone.js'siz (zoneless) default CD qanday ishlaydi?

Yodlash uchun

Default = har event'dan keyin butun tree tekshiriladi; Zone.js odatda trigger qiladi.

### OnPush strategy — faqat @Input, event, async pipe
Middle

Nima bu?

ChangeDetectionStrategy.OnPush komponentni faqat quyidagi holatlarda tekshiradi: yangi @Input reference; komponent ichidagi event; async pipe yangi qiymat olganda; markForCheck() chaqirilganda. Immutable data pattern bilan performance sezilarli yaxshilanadi.

Nega async pipe OnPush bilan "sehrli" ishlaydi: AsyncPipe ichida subscribe() chaqiriladi, va har emit'da pipe o'zi ChangeDetectorRef.markForCheck() ni chaqiradi — bu template'dagi boshqa hech qanday RxJS subscribe (masalan komponent kodida qo'lda .subscribe()) qilmaydi. Shuning uchun OnPush komponentda ma'lumotni qo'lda subscribe qilib class field'ga yozsangiz, view yangilanmay qoladi — sabab input reference o'zgarmagani, async pipe esa yo'q. Bu — real interview'da eng ko'p uchraydigan OnPush "capqoni".

Kod misoli

import { Component, ChangeDetectionStrategy, Input } from '@angular/core';
import { AsyncPipe } from '@angular/common';
import { Observable, of } from 'rxjs';

interface Todo {
  id: number;
  title: string;
  done: boolean;
}

@Component({
  selector: 'app-todo-item',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <label>
      <input type="checkbox" [checked]="todo.done" (change)="toggle()" />
      {{ todo.title }}
    </label>
  `,
})
export class TodoItemComponent {
  @Input({ required: true }) todo!: Todo;
  @Input() onToggle!: (id: number) => void;

  toggle(): void {
    this.onToggle(this.todo.id);
  }
}

@Component({
  selector: 'app-todo-list',
  standalone: true,
  imports: [TodoItemComponent, AsyncPipe],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    @for (todo of todos$ | async; track todo.id) {
      <app-todo-item [todo]="todo" [onToggle]="toggleTodo" />
    }
  `,
})
export class TodoListComponent {
  todos$ = of<Todo[]>([
    { id: 1, title: 'Angular o\'rganish', done: false },
  ]);

  toggleTodo = (id: number): void => {
    // Immutable update — yangi array reference
  };
}

Imtihonda

  • OnPush'da ob'ekt property'sini mutate qilsa nima bo'ladi?
  • async pipe nima uchun OnPush bilan yaxshi juft?
  • Barcha komponentlarni OnPush qilish mumkinmi?
  • OnPush komponentda service'dan qo'lda .subscribe() qilib class field yangilansa, nega view yangilanmaydi?

Yodlash uchun

OnPush = input ref o'zgarishi, event, async pipe, markForCheck; mutate emas, replace.

### ChangeDetectorRef — markForCheck, detectChanges
MiddleSenior

Nima bu?

ChangeDetectorRef komponentning change detection tsiklini qo'lda boshqarish uchun inject qilinadi. markForCheck() — keyingi CD tsiklda tekshirish (OnPush uchun); detach() — CD'dan ajratish; detectChanges() — darhol shu komponent va child'larni tekshirish; reattach() — qayta ulash.

Kod misoli

import {
  Component,
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  inject,
  OnInit,
  OnDestroy,
} from '@angular/core';

@Component({
  selector: 'app-live-price',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `<p>Narx: {{ price }} so'm</p>`,
})
export class LivePriceComponent implements OnInit, OnDestroy {
  price = 0;
  private cdr = inject(ChangeDetectorRef);
  private timerId?: ReturnType<typeof setInterval>;

  ngOnInit(): void {
    // setInterval Zone tashqarisida — markForCheck kerak
    this.timerId = setInterval(() => {
      this.price += Math.floor(Math.random() * 1000);
      this.cdr.markForCheck();
    }, 2000);
  }

  forceUpdate(): void {
    this.cdr.detectChanges(); // darhol tekshir
  }

  ngOnDestroy(): void {
    clearInterval(this.timerId);
  }
}

Imtihonda

  • markForCheck() vs detectChanges() farqi?
  • detach() qachon foydali (virtual scroll)?
  • OnPush + WebSocket/stream'da qanday yangilash?

Yodlash uchun

markForCheck — keyingi tsikl; detectChanges — hozir; OnPush + tashqi event = markForCheck.

### Zoneless Angular — zone.js'siz (v18+)
Senior

Nima bu?

Zoneless Angular zone.js kutubxonasiz change detection ishlaydi. Hodisalar va signallar o'zgarishi orqali CD aniq trigger qilinadi — bundle kichikroq, debug osonroq, performance bashorat qilinadigan. Angular 18+ da provideExperimentalZonelessChangeDetection() bilan yoqiladi.

Zone.js aslida nima qiladi: u brauzer API'larini (setTimeout, addEventListener, Promise, XHR) monkey-patch qiladi va har birining tugashidan keyin Angular'ga "signal" beradi — shu signal butun daraxt bo'ylab CD'ni ishga tushiradi. Bu — nega ba'zan kutilmagan joyda (masalan uchinchi tomon kutubxona ichidagi event) ham CD ishga tushishi yoki, aksincha, runOutsideAngular() bilan ataylab zone'dan tashqariga chiqarilgan kod CD trigger qilmasligi mumkinligining sababi. Zoneless'da bunday "yashirin" trigger yo'q — har bir signal yangilanishi aniq va bashorat qilinadigan, lekin zone tashqarisidagi eski (signal ishlatmaydigan) kod endi CD'ni avtomatik trigger qilmaydi — shuning uchun migratsiya paytida signal'ga o'tmagan komponentlar "muzlab qolishi" mumkin.

Kod misoli

// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import {
  provideExperimentalZonelessChangeDetection,
} from '@angular/core';
import { AppComponent } from './app/app.component';

bootstrapApplication(AppComponent, {
  providers: [
    provideExperimentalZonelessChangeDetection(),
  ],
});
import { Component, signal, computed } from '@angular/core';

@Component({
  selector: 'app-zoneless-counter',
  standalone: true,
  template: `
    <p>{{ count() }}</p>
    <p>Kvadrat: {{ squared() }}</p>
    <button type="button" (click)="increment()">+1</button>
  `,
})
export class ZonelessCounterComponent {
  count = signal(0);
  squared = computed(() => this.count() ** 2);

  increment(): void {
    this.count.update(v => v + 1);
    // Zoneless: signal o'zgarishi CD ni avtomatik trigger qiladi
  }
}

Imtihonda

  • Zone.js nima qiladi va nega olib tashlanmoqda?
  • Zoneless'da setTimeout ichidagi o'zgarish qanday ko'rinadi?
  • Migratsiya strategiyasi qanday?
  • NgZone.runOutsideAngular() nima uchun ishlatiladi va zoneless'da bu tushuncha qanday o'zgaradi?

Yodlash uchun

Zoneless = signal + explicit CD; zone.js ixtiyoriy; v18+ experimental provider.

Prev
Template
Next
Advanced Component