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

State management (service)

Daraja:

Kichik va o'rta ilovalar uchun NgRx'siz service-based state yetarli. BehaviorSubject an'anaviy, signal() esa Angular 17+ da zamonaviy yondashuv.

BehaviorSubject pattern — local state

Middle

Nima bu?

BehaviorSubject oxirgi qiymatni saqlaydigan hot Observable. Service ichida private BehaviorSubject, tashqariga faqat asObservable() (readonly) beriladi. Component'lar subscribe qiladi yoki async pipe ishlatadi. Bu RxJS asosidagi sodda store pattern.

Gotcha: async pipe subscribe'ni komponent yo'q qilinganda avtomatik bekor qiladi, lekin komponent ichida qo'lda .subscribe() qilingan bo'lsa, ngOnDestroy'da unsubscribe() qilinmasa memory leak yuzaga keladi — service providedIn: 'root' bo'lgani uchun Subject butun ilova umri davomida yashaydi va subscriber'lar to'planib boraveradi. Zamonaviy yechim: takeUntilDestroyed() operatori yoki iloji boricha async pipe'dan foydalanish.

Kod misoli

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';

interface CartItem {
  id: number;
  name: string;
  qty: number;
}

interface CartState {
  items: CartItem[];
  loading: boolean;
}

const initialState: CartState = { items: [], loading: false };

@Injectable({ providedIn: 'root' })
export class CartStore {
  private state$ = new BehaviorSubject<CartState>(initialState);

  // Faqat o'qish — tashqaridan next() chaqirish mumkin emas
  readonly cart$ = this.state$.asObservable();
  readonly total$ = this.cart$.pipe(
    map((s) => s.items.reduce((sum, i) => sum + i.qty, 0))
  );

  addItem(item: CartItem): void {
    const current = this.state$.value;
    const existing = current.items.find((i) => i.id === item.id);
    const items = existing
      ? current.items.map((i) =>
          i.id === item.id ? { ...i, qty: i.qty + item.qty } : i
        )
      : [...current.items, item];
    this.state$.next({ ...current, items });
  }

  setLoading(loading: boolean): void {
    this.state$.next({ ...this.state$.value, loading });
  }

  clear(): void {
    this.state$.next(initialState);
  }
}
@Component({
  selector: 'app-cart-badge',
  standalone: true,
  imports: [AsyncPipe],
  template: `Savat: {{ total$ | async }}`,
})
export class CartBadgeComponent {
  total$ = inject(CartStore).total$;
}

Imtihonda

Savol: Nima uchun BehaviorSubject ni to'g'ridan-to'g'ri expose qilmaslik kerak?

Javob: Tashqi kod .next() chaqirib state'ni buzishi mumkin. asObservable() — faqat o'qish. O'zgartirish faqat service metodlari orqali.

Yodlash uchun

Private BehaviorSubject + public asObservable() + update metodlari. Immutable update: `{ ...state, items }`.

Signal-based store (v17+)

MiddleSenior

Nima bu?

Angular Signals (signal, computed, update) service ichida reaktiv state boshqarish uchun ishlatiladi. Subscribe/unsubscribe kerak emas — template'da to'g'ridan-to'g'ri store.items() chaqiriladi. computed derived state uchun, effect side-effect uchun.

Kod misoli

import { Injectable, computed, signal } from '@angular/core';

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

@Injectable({ providedIn: 'root' })
export class TodoStore {
  private _todos = signal<Todo[]>([]);
  private _filter = signal<'all' | 'active' | 'done'>('all');

  readonly todos = this._todos.asReadonly();
  readonly filter = this._filter.asReadonly();

  readonly filteredTodos = computed(() => {
    const list = this._todos();
    const f = this._filter();
    if (f === 'active') return list.filter((t) => !t.done);
    if (f === 'done') return list.filter((t) => t.done);
    return list;
  });

  readonly activeCount = computed(
    () => this._todos().filter((t) => !t.done).length
  );

  addTodo(title: string): void {
    this._todos.update((list) => [
      ...list,
      { id: Date.now(), title, done: false },
    ]);
  }

  toggle(id: number): void {
    this._todos.update((list) =>
      list.map((t) => (t.id === id ? { ...t, done: !t.done } : t))
    );
  }

  setFilter(filter: 'all' | 'active' | 'done'): void {
    this._filter.set(filter);
  }
}
@Component({
  selector: 'app-todo-list',
  standalone: true,
  template: `
    <p>Faol: {{ store.activeCount() }}</p>
    @for (todo of store.filteredTodos(); track todo.id) {
      <label>
        <input type="checkbox" [checked]="todo.done" (change)="store.toggle(todo.id)" />
        {{ todo.title }}
      </label>
    }
  `,
})
export class TodoListComponent {
  store = inject(TodoStore);
}

Imtihonda

Savol: Signal store va BehaviorSubject — qaysi biri OnPush bilan yaxshiroq ishlaydi?

Javob: Signal — Angular signal-based change detection bilan to'g'ridan-to'g'ri integratsiya. BehaviorSubject + async pipe ham OnPush'da yaxshi, lekin subscribe boilerplate ko'proq.

Yodlash uchun

Signal store: private `signal()` + public `asReadonly()` + `computed()` derived state. RxJS kerak bo'lsa `toObservable()` bridge.
Prev
Advanced DI