Component
Nima bu?
@Component dekoratori Angular klassini UI komponentiga aylantiradi. selector — template'da ishlatiladigan HTML teg yoki atribut; template yoki templateUrl — ko'rinish; styles yoki styleUrl — komponentga xos CSS. Angular bu metadatadan komponentni compile qiladi va DOM ga ulaydi.
Kod misoli
import { Component } from '@angular/core';
@Component({
selector: 'app-user-card',
standalone: true,
template: `
<article class="card">
<h2>{{ name }}</h2>
<p>{{ email }}</p>
</article>
`,
styles: [`
.card { padding: 1rem; border: 1px solid #ccc; border-radius: 8px; }
`],
})
export class UserCardComponent {
name = 'Ali Valiyev';
email = 'ali@example.com';
}
<!-- parent template -->
<app-user-card></app-user-card>
Imtihonda
@Componentmetadata maydonlari qaysilar?selector'app-user-card'va'[appUserCard]'farqi nima?templateUrlvs inlinetemplateqachon tanlanadi?
Yodlash uchun
Har bir komponent bitta @Component dekoratoriga ega; selector unikal bo'lishi kerak.
Nima bu?
Standalone komponent standalone: true bilan NgModule'siz ishlaydi. Kerakli directive, pipe va boshqa komponentlar imports massivida ko'rsatiladi. Angular 14+ da tavsiya etilgan yondashuv; bootstrapApplication() bilan to'liq module'siz ilova ishga tushadi.
Kod misoli
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
import { UserAvatarComponent } from './user-avatar.component';
@Component({
selector: 'app-profile',
standalone: true,
imports: [CommonModule, RouterLink, UserAvatarComponent],
template: `
<app-user-avatar [name]="userName" />
<a [routerLink]="['/users', id]">{{ userName }}</a>
@if (isActive) {
<span class="badge">Faol</span>
}
`,
})
export class ProfileComponent {
id = 42;
userName = 'Sardor';
isActive = true;
}
Imtihonda
- Standalone komponentda
declarationso'rniga nima ishlatiladi? - NgModule'dan standalone'ga migratsiya qanday boshlanadi?
importsga faqat komponent emas, directive va pipe ham qo'shiladimi?
Yodlash uchun
Standalone = standalone: true + imports: [...]; NgModule talab qilinmaydi.
Nima bu?
Angular to'rtta asosiy binding turini qo'llab-quvvatlaydi: interpolation {{ }} — klassdan template'ga ma'lumot; property binding [prop] — DOM xususiyatiga qiymat; event binding (event) — hodisani ushlash; two-way binding [(ngModel)] — ikki yo'nalishli bog'lanish (FormsModule kerak).
Kod misoli
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-binding-demo',
standalone: true,
imports: [FormsModule],
template: `
<p>Salom, {{ title }}!</p>
<img [src]="imageUrl" [alt]="title" />
<button [disabled]="isSaving" (click)="save()">Saqlash</button>
<input [(ngModel)]="title" />
<p>Siz kiritdingiz: {{ title }}</p>
`,
})
export class BindingDemoComponent {
title = 'Angular';
imageUrl = '/assets/logo.png';
isSaving = false;
save(): void {
this.isSaving = true;
setTimeout(() => (this.isSaving = false), 1000);
}
}
Imtihonda
[disabled]="false"vadisabled="false"farqi nima?- Two-way binding ichki mexanizmi qanday (
[()]banana in a box)? (click)="save($event)"da$eventnima?
Yodlash uchun
{{ }} chiqish, [ ] kirish, ( ) hodisa, [( )] ikki yo'nalish.
Nima bu?
Lifecycle hooks komponent yaratilish, yangilanish va yo'q qilinish bosqichlarida kod ishga tushirish imkonini beradi. ngOnChanges — @Input o'zgarganda; ngOnInit — birinchi @Input set qilingandan keyin; ngAfterViewInit — view (child komponentlar) tayyor bo'lganda; ngOnDestroy — komponent yo'q qilinayotganda (unsubscribe uchun).
Kod misoli
import {
Component,
Input,
OnChanges,
OnInit,
AfterViewInit,
OnDestroy,
SimpleChanges,
} from '@angular/core';
import { Subscription, interval } from 'rxjs';
@Component({
selector: 'app-timer',
standalone: true,
template: `<p>Count: {{ count }}</p>`,
})
export class TimerComponent implements OnInit, OnChanges, AfterViewInit, OnDestroy {
@Input() startFrom = 0;
count = 0;
private sub?: Subscription;
ngOnChanges(changes: SimpleChanges): void {
if (changes['startFrom'] && !changes['startFrom'].firstChange) {
this.count = changes['startFrom'].currentValue;
}
}
ngOnInit(): void {
this.count = this.startFrom;
this.sub = interval(1000).subscribe(() => this.count++);
}
ngAfterViewInit(): void {
console.log('View tayyor, count:', this.count);
}
ngOnDestroy(): void {
this.sub?.unsubscribe();
}
}
Imtihonda
constructorvsngOnInit— HTTP so'rov qayerda chaqiriladi?ngOnChangesqachon chaqirilmaydi (bir xil reference)?ngOnDestroyda nima tozalash kerak?
Yodlash uchun
Init — setup, AfterViewInit — DOM/child, OnDestroy — cleanup; hooks tartibini bil.
Nima bu?
@Input() — parentdan child'ga ma'lumot uzatish; @Output() — child'dan parent'ga hodisa yuborish (EventEmitter orqali). Bu unidirectional data flow'ning asosi: parent state boshqaradi, child faqat ko'rsatadi va hodisa chiqaradi.
Kod misoli
// child: rating-stars.component.ts
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-rating-stars',
standalone: true,
template: `
@for (star of [1,2,3,4,5]; track star) {
<button type="button" (click)="select(star)">
{{ star <= value ? '★' : '☆' }}
</button>
}
`,
})
export class RatingStarsComponent {
@Input() value = 0;
@Output() valueChange = new EventEmitter<number>();
select(star: number): void {
this.valueChange.emit(star);
}
}
<!-- parent template -->
<app-rating-stars
[value]="productRating"
(valueChange)="productRating = $event"
/>
Imtihonda
@Output()nomi va template'dagi(nom)qanday bog'lanadi?EventEmitterObservable emasmi, nega.emit()ishlatiladi?- Parent-child aloqa o'rniga service qachon yaxshiroq?
Yodlash uchun
Input pastga, Output yuqoriga; EventEmitter.emit() bilan hodisa yubor.
Nima bu?
Angular 16+ da @Input({ required: true }) majburiy input ekanligini compile va runtime'da bildiradi. Parent template'da bu input berilmasa build vaqtida xato yoki runtime'da ogohlantirish chiqadi. Optional inputlar uchun default qiymat yoki undefined qabul qilinadi.
Kod misoli
import { Component, Input } from '@angular/core';
export interface Product {
id: number;
name: string;
price: number;
}
@Component({
selector: 'app-product-price',
standalone: true,
template: `
<span class="price">{{ product.name }}: {{ product.price | currency:'UZS' }}</span>
`,
})
export class ProductPriceComponent {
@Input({ required: true }) product!: Product;
@Input() showTax = false;
}
<!-- to'g'ri -->
<app-product-price [product]="selectedProduct" />
<!-- xato: product berilmagan -->
<app-product-price />
Imtihonda
required: trueva TypeScript!(definite assignment) farqi?- Strict templates bilan qanday ishlaydi?
- Required input uchun default qiymat berish mumkinmi?
Yodlash uchun
Majburiy input = @Input({ required: true }); parent har doim uzatishi shart.
Nima bu?
Signal-based komponent API: input() — @Input o'rniga signal input (Angular 17.1), output() — @Output o'rniga (Angular 17.3), model() — two-way binding uchun, value + valueChange birgalikda (Angular 17.2). Bu reactive, type-safe va change detection bilan yaxshi integratsiyalangan.
Muhim farq: dekorator-based @Input() o'zgarganda ngOnChanges chaqiriladi, lekin signal input() uchun bunday hook yo'q — o'rniga computed() yoki effect() ichida signalni o'qib reaksiya yozasiz. Yana bir nuance: signal input OnPush komponentda ham, Default strategiyada ham bir xil ishlaydi, chunki signal o'qilganda Angular avtomatik dependency track qiladi va faqat kerakli joyni yangilaydi (fine-grained reactivity) — bu klassik markForCheck() chaqirishga ehtiyojni yo'qotadi, @Input() + OnPush'da esa reference o'zgarishi kerak edi.
Kod misoli
import { Component, input, output, model, computed } from '@angular/core';
@Component({
selector: 'app-counter',
standalone: true,
template: `
<button type="button" (click)="decrement()">-</button>
<span>{{ displayValue() }}</span>
<button type="button" (click)="increment()">+</button>
`,
})
export class CounterComponent {
count = model(0);
step = input(1);
maxReached = output<number>();
displayValue = computed(() => this.count());
increment(): void {
const next = this.count() + this.step();
this.count.set(next);
if (next >= 10) this.maxReached.emit(next);
}
decrement(): void {
this.count.update(v => v - this.step());
}
}
<app-counter [(count)]="total" [step]="2" (maxReached)="onMax($event)" />
Imtihonda
input()va@Input()change detection farqi?model()qanday two-way binding hosil qiladi?- Signal input'ni template'da
count()deb chaqirish shartmi? - Signal input o'zgarganda nega
ngOnChangeschaqirilmaydi, o'rniga nima ishlatiladi?
Yodlash uchun
Yangi API: input(), output(), model() — signal asosida; model() = input + output birga.
