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

Komponent arxitekturasi

Daraja:

Katta Angular ilovalarida komponentlarni Smart (Container) va Dumb (Presentation) ga ajratish, @Input/@Output orqali bir yo'nalishli data flow va service/state orqali aloqa — maintainability va test qilishni osonlashtiradi.

Smart (Container) vs Dumb (Presentation) component

Middle

Nima bu?

Smart (Container) komponent — biznes logika, HTTP, store bilan ishlaydi; state boshqaradi va Dumb komponentlarga data uzatadi. Dumb (Presentation) komponent — faqat @Input orqali data oladi, @Output orqali event yuboradi; service inject qilmaydi, qayta ishlatiladigan UI bo'ladi. Bu pattern test va refactor'ni soddalashtiradi.

Kod misoli

// Dumb — faqat ko'rsatish
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
import { CurrencyPipe } from '@angular/common';

export interface Product {
  id: number;
  name: string;
  price: number;
}

@Component({
  selector: 'app-product-card',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <article class="card">
      <h3>{{ product.name }}</h3>
      <p>{{ product.price | currency:'UZS':'symbol':'1.0-0' }}</p>
      <button type="button" (click)="addToCart.emit(product.id)">
        Savatga
      </button>
    </article>
  `,
  imports: [CurrencyPipe],
})
export class ProductCardComponent {
  @Input({ required: true }) product!: Product;
  @Output() addToCart = new EventEmitter<number>();
}
// Smart — data va logika
import { Component, inject, Output, EventEmitter } from '@angular/core';
import { AsyncPipe } from '@angular/common';
import { ProductCardComponent, Product } from './product-card.component';
import { ProductService } from './product.service';
import { CartService } from './cart.service';

@Component({
  selector: 'app-product-list-page',
  standalone: true,
  imports: [ProductCardComponent, AsyncPipe],
  template: `
    @if (products$ | async; as products) {
      <div class="grid">
        @for (p of products; track p.id) {
          <app-product-card
            [product]="p"
            (addToCart)="onAddToCart($event)"
          />
        }
      </div>
    }
  `,
})
export class ProductListPageComponent {
  private productService = inject(ProductService);
  private cartService = inject(CartService);

  products$ = this.productService.getProducts();

  onAddToCart(productId: number): void {
    this.cartService.add(productId);
  }
}

Imtihonda

  • Smart komponent qaysi mas'uliyatlarni oladi?
  • Dumb komponentda service inject qilish nima uchun tavsiya etilmaydi?
  • Bu pattern OnPush bilan qanday uyg'unlashadi?

Yodlash uchun

Smart = state + logika; Dumb = Input/Output, UI only.

@Input/@Output convention — unidirectional flow

Middle

Nima bu?

Unidirectional data flow — data yuqoridan pastga @Input orqali oqadi, o'zgarishlar pastdan yuqoriga @Output event orqali xabar qilinadi. Parent @Input ni o'zgartiradi; child @Input ni mutate qilmasligi kerak. Angular 17.1+ da input() va output() signal-based API ham mavjud. Naming: Input — noun (user, items), Output — verb (save, delete, selectedChange).

Kod misoli

import { Component, inject, input, output, computed } from '@angular/core';

interface UserForm {
  name: string;
  email: string;
}

@Component({
  selector: 'app-user-form',
  standalone: true,
  template: `
    <form (ngSubmit)="submit()">
      <input [value]="value().name"
             (input)="patch({ name: $any($event.target).value })" />
      <input [value]="value().email"
             (input)="patch({ email: $any($event.target).value })" />
      <button type="submit" [disabled]="!isValid()">Saqlash</button>
      <button type="button" (click)="cancelled.emit()">Bekor</button>
    </form>
  `,
})
export class UserFormComponent {
  // Signal-based Input/Output (Angular 17.1+)
  value = input.required<UserForm>();
  save = output<UserForm>();
  cancelled = output<void>();

  isValid = computed(() =>
    this.value().name.trim().length > 0 &&
    this.value().email.includes('@')
  );

  private patch(partial: Partial<UserForm>): void {
    // Child Input'ni mutate qilmaydi — event yuboradi
    this.save.emit({ ...this.value(), ...partial });
  }

  submit(): void {
    if (this.isValid()) {
      this.save.emit(this.value());
    }
  }
}
// Parent — state egasi
@Component({
  selector: 'app-user-page',
  standalone: true,
  imports: [UserFormComponent],
  template: `
    <app-user-form
      [value]="formState"
      (save)="onSave($event)"
      (cancelled)="onCancel()"
    />
  `,
})
export class UserPageComponent {
  formState: UserForm = { name: '', email: '' };

  onSave(data: UserForm): void {
    this.formState = { ...data }; // immutable update
    console.log('Saqlash:', data);
  }

  onCancel(): void {
    this.formState = { name: '', email: '' };
  }
}

Imtihonda

  • Child @Input ob'ektini mutate qilsa nima bo'ladi (OnPush bilan)?
  • selectedChange naming convention qayerdan keladi?
  • input() / output() va @Input / @Output farqi?

Yodlash uchun

Data pastga (Input), event yuqoriga (Output); child state mutate qilmasin.

Component communication — service, state

Middle

Nima bu?

Sibling yoki uzoq parent-child zanjirida @Input/@Output yetarli emas — shared service yoki state store ishlatiladi. BehaviorSubject, signal() store, yoki @Injectable({ providedIn: 'root' }) event bus. Component communication usullari: Input/Output (direct), @ViewChild (parent → child), service (any), RxJS Subject, NgRx/Signals store (katta ilova).

Kod misoli

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

export interface Toast {
  id: number;
  message: string;
  type: 'success' | 'error';
}

@Injectable({ providedIn: 'root' })
export class ToastService {
  private toasts = signal<Toast[]>([]);
  readonly items = computed(() => this.toasts());

  show(message: string, type: Toast['type'] = 'success'): void {
    const id = Date.now();
    this.toasts.update((list) => [...list, { id, message, type }]);
    setTimeout(() => this.dismiss(id), 4000);
  }

  dismiss(id: number): void {
    this.toasts.update((list) => list.filter((t) => t.id !== id));
  }
}
// Producer — Smart komponent
@Component({
  selector: 'app-checkout',
  standalone: true,
  template: `<button type="button" (click)="pay()">To'lash</button>`,
})
export class CheckoutComponent {
  private toast = inject(ToastService);
  private orderService = inject(OrderService);

  pay(): void {
    this.orderService.submit().subscribe({
      next: () => this.toast.show('Buyurtma qabul qilindi'),
      error: () => this.toast.show('Xato yuz berdi', 'error'),
    });
  }
}
// Consumer — Dumb komponent (global toast)
@Component({
  selector: 'app-toast-container',
  standalone: true,
  template: `
    <div class="toast-stack">
      @for (t of toastService.items(); track t.id) {
        <div [class]="'toast toast-' + t.type">{{ t.message }}</div>
      }
    </div>
  `,
})
export class ToastContainerComponent {
  toastService = inject(ToastService);
}

Imtihonda

  • Qachon service, qachon Input/Output tanlanadi?
  • providedIn: 'root' va component-level provider farqi?
  • EventEmitter va Subject farqi (Output vs service)?

Yodlash uchun

Sibling/uzoq aloqa → service; yaqin parent-child → Input/Output.

Angular Signals store kichik ilovalar uchun NgRx'siz yetarli — `computed` va `signal` bilan reactive state.
Prev
Angular 17+ yangi sintaksis
Next
Performance pattern'lar