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

Hierarchical DI

Daraja:

Angular DI iyerarxik — root injector'dan boshlab component daraxti bo'ylab pastga qarab injector'lar zanjiri hosil bo'ladi. Bir xil service turli darajalarda turli instance bo'lishi mumkin.

DI iyerarxiyasi — root, module, component

Middle

Nima bu?

Angular injector'lar daraxti:

  1. Root injector — providedIn: 'root' service'lar shu yerda (singleton).
  2. Module/Route injector — lazy modul yoki providers bilan modul darajasida.
  3. Component injector — component providers array'i — component va uning bolalari uchun alohida scope.

Component dependency so'raganda Angular avval o'z injector'idan, keyin ota injector'lardan qidiradi (yuqoriga chiqadi).

Klassik capqon — lazy-loaded route/modul: agar providedIn: 'root' bo'lgan service lazy modulning o'z providers massivida qayta ko'rsatilsa, root singleton ustiga emas, balki shu lazy modul uchun yangi, alohida instance yaratiladi (root injector emas, module injector'da). Natijada ilova boshqa joyida root instance, lazy modul ichida esa boshqa instance ishlaydi — state "sinxronlanmaydi". Buni interview'da ko'pincha "nega mening singleton service ikkita nusxada ishlayapti?" savoli sifatida so'rashadi.

Kod misoli

@Injectable()
export class LoggerService {
  constructor(public id: string = crypto.randomUUID()) {}
  log(msg: string): void {
    console.log(`[${this.id}] ${msg}`);
  }
}

// Root — bitta instance
@Injectable({ providedIn: 'root' })
export class AppConfigService {
  apiUrl = '/api';
}

// Component scope — har bir AdminPanel uchun alohida Logger
@Component({
  selector: 'app-admin-panel',
  standalone: true,
  providers: [LoggerService], // yangi instance shu subtree uchun
  template: `<app-admin-child />`,
})
export class AdminPanelComponent {
  constructor(public logger: LoggerService) {}
}

@Component({
  selector: 'app-admin-child',
  standalone: true,
  template: ``,
})
export class AdminChildComponent {
  constructor(public logger: LoggerService) {} // ota bilan bir xil instance
}

Imtihonda

Savol: Root'dagi service va component providers dagi bir xil class — bir instancemi?

Javob: Yo'q. Component providers yangi injector yaratadi — subtree uchun alohida instance. Root singleton emas.

Savol: providedIn: 'root' service lazy-loaded modulning providers ro'yxatida ham ko'rsatilsa nima bo'ladi?

Javob: Root singleton bilan bir qatorda, shu lazy modul uchun ikkinchi, mustaqil instance yaratiladi — ikkalasi orasida state umumiy bo'lmaydi.

Yodlash uchun

Qidirish yo'nalishi: component → ota component → ... → root. `providedIn: 'root'` — eng yuqori daraja singleton.

providers: [] — component darajasida yangi instance

Middle

Nima bu?

Component metadata'sidagi providers: [SomeService] shu component va uning barcha child component'lari uchun yangi DI scope yaratadi. Har bir component instance'i o'z service instance'ini oladi. Form wizard, tab panel, route-specific state uchun foydali.

Kod misoli

@Injectable()
export class WizardStateService {
  step = signal(1);
  data = signal<Record<string, unknown>>({});

  nextStep(): void {
    this.step.update((s) => s + 1);
  }
}

@Component({
  selector: 'app-wizard',
  standalone: true,
  providers: [WizardStateService],
  template: `
    <p>Qadam: {{ state.step() }}</p>
    <app-wizard-step />
    <button (click)="state.nextStep()">Keyingi</button>
  `,
})
export class WizardComponent {
  state = inject(WizardStateService);
}

@Component({
  selector: 'app-wizard-step',
  standalone: true,
  template: `<input (input)="state.data.update(d => ({...d, name: $event.target.value}))" />`,
})
export class WizardStepComponent {
  state = inject(WizardStateService); // ota Wizard bilan bir xil instance
}
<!-- Ikkita wizard — alohida state -->
<app-wizard />
<app-wizard />

Imtihonda

Savol: @Injectable({ providedIn: 'root' }) bo'lgan service'ni component providers ga qo'shsak nima bo'ladi?

Javob: Component subtree uchun yangi instance yaratiladi — root singleton ustiga yoziladi (shadow). Tashqaridagi component'lar hali root instance'ni oladi.

Yodlash uchun

Component scope = component + barcha bolalar. Ikki ``app-wizard`` = ikki alohida state.

@SkipSelf, @Self, @Optional dekoratorlari

Senior

Nima bu?

Injector qidirish yo'nalishini boshqaruvchi parameter dekoratorlar:

  • @Self() — faqat o'z injector'idan qidir (ota injector'ga chiqma).
  • @SkipSelf() — o'z injector'ini o'tkazib, ota injector'dan boshla.
  • @Optional() — topilmasa null qaytar (xato emas).
  • @Host() — @Self() dan farqli, o'z injector'ini ham qidiradi, lekin qidiruvni host component chegarasidan oshirmaydi (undan yuqoriga — masalan root injector'ga — chiqmaydi).

Kod misoli

@Injectable()
export class ThemeService {
  theme = signal<'light' | 'dark'>('light');
}

@Component({
  selector: 'app-themed-card',
  standalone: true,
  providers: [ThemeService],
  template: `<app-themed-inner />`,
})
export class ThemedCardComponent {
  constructor(@Self() public theme: ThemeService) {}
  // Self — faqat shu component injector'idagi ThemeService
}

@Component({
  selector: 'app-themed-inner',
  standalone: true,
  template: `<p>Tema: {{ parentTheme?.theme() ?? 'default' }}</p>`,
})
export class ThemedInnerComponent {
  constructor(
    @SkipSelf() @Optional() public parentTheme: ThemeService | null
  ) {}
  // SkipSelf — o'z injector'ini o'tkaz, ota ThemedCard'dan ol
}

// CoreModule guard pattern — bu guard faqat @NgModule uchun ishlaydi,
// chunki Angular NgModule import qilinganda uni avtomatik instantiate qiladi
@NgModule({})
export class CoreModule {
  constructor(@Optional() @SkipSelf() parent: CoreModule) {
    if (parent) {
      throw new Error('CoreModule ikki marta import qilinmasin');
    }
  }
}

Imtihonda

Savol: @Self() va @SkipSelf() qachon kerak?

Javob: @Self() — faqat shu darajadagi provider kerak (masalan, component o'zi provider). @SkipSelf() — o'zini o'tkazib ota/root'dan olish (CoreModule guard, parent service'ga murojaat).

Yodlash uchun

Self = faqat men. SkipSelf = meni o'tkaz. Optional = topilmasa null. Host = host chegarasigacha.
Prev
HTTP
Next
Advanced DI