Custom Pipe
Nima bu?
Custom pipe @Pipe dekoratori va PipeTransform interfeysi orqali yaratiladi. name — template'da ishlatiladigan nom; transform(value, ...args) metodi qiymatni qayta ishlaydi. Standalone pipe imports ga qo'shiladi.
Kod misoli
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'truncate',
standalone: true,
})
export class TruncatePipe implements PipeTransform {
transform(value: string | null | undefined, limit = 50, suffix = '...'): string {
if (!value) return '';
if (value.length <= limit) return value;
return value.slice(0, limit).trimEnd() + suffix;
}
}
import { Component } from '@angular/core';
import { TruncatePipe } from './truncate.pipe';
@Component({
selector: 'app-article-preview',
standalone: true,
imports: [TruncatePipe],
template: `
<h3>{{ article.title }}</h3>
<p>{{ article.body | truncate:120:'…' }}</p>
`,
})
export class ArticlePreviewComponent {
article = {
title: 'Angular Pipe yaratish',
body: 'Pipe transformatsiya logikasini template\'dan ajratib, qayta ishlatiladigan qiladi. Bu kod sizishni kamaytiradi va test qilishni osonlashtiradi.',
};
}
Imtihonda
PipeTransformmetodi signature qanday?- Pipe nomi camelCase yoki kebab-case?
- Pure pipe default holatimi?
Yodlash uchun
@Pipe + PipeTransform.transform(); standalone imports'ga qo'sh.
Nima bu?
Default pure pipe (pure: true) faqat input reference yoki primitiv qiymat o'zgarganda transform() chaqiradi. Angular oldingi natijani cache qiladi — tez va samarali. Ob'ekt ichidagi o'zgarishni sezmaydi (immutable data kerak).
Kod misoli
import { Pipe, PipeTransform } from '@angular/core';
interface Order {
items: { name: string; qty: number; price: number }[];
}
@Pipe({
name: 'orderTotal',
standalone: true,
pure: true, // default
})
export class OrderTotalPipe implements PipeTransform {
transform(order: Order | null): number {
if (!order?.items?.length) return 0;
return order.items.reduce((sum, item) => sum + item.qty * item.price, 0);
}
}
<p>Jami: {{ order | orderTotal | currency:'UZS':'symbol-narrow':'1.0-0' }}</p>
<!-- order reference o'zgarmaguncha pipe qayta ishlamaydi -->
// To'g'ri: yangi reference
this.order = { ...this.order, items: [...this.order.items, newItem] };
// Noto'g'ri: mutate — pure pipe yangilanmaydi
this.order.items.push(newItem);
Imtihonda
- Pure pipe qachon qayta hisoblanadi?
- Ob'ekt property o'zgarganda nima bo'ladi?
- Pure pipe xavfsizligi (side effect)?
Yodlash uchun
Pure = input ref/qiymat o'zgarishi; default; immutable data.
Nima bu?
Impure pipe (pure: false) har change detection tsiklida transform() chaqiriladi — ob'ekt ichidagi o'zgarishlarni ham sezadi. Lekin performance yukini oshiradi; faqat zarur holatlarda (real-time filter, mutable state) ishlatiladi.
Kod misoli
import { Pipe, PipeTransform } from '@angular/core';
import { FormsModule } from '@angular/forms';
interface Todo {
title: string;
done: boolean;
}
@Pipe({
name: 'filterTodos',
standalone: true,
pure: false,
})
export class FilterTodosPipe implements PipeTransform {
transform(todos: Todo[], showDone = false): Todo[] {
console.log('filterTodos ishga tushdi'); // har CD'da
if (showDone) return todos;
return todos.filter(t => !t.done);
}
}
@Component({
selector: 'app-todo-filter',
standalone: true,
imports: [FilterTodosPipe, FormsModule],
template: `
<label>
<input type="checkbox" [(ngModel)]="showDone" /> Bajarilganlarni ko'rsat
</label>
<ul>
@for (todo of todos | filterTodos:showDone; track todo.title) {
<li>{{ todo.title }}</li>
}
</ul>
<button type="button" (click)="addTodo()">Qo'shish</button>
`,
})
export class TodoFilterComponent {
showDone = false;
todos: Todo[] = [
{ title: 'Angular o\'qish', done: false },
{ title: 'Pipe yozish', done: true },
];
addTodo(): void {
this.todos.push({ title: 'Yangi vazifa', done: false }); // mutate — impure kerak
}
}
Imtihonda
- Impure pipe qachon kerak?
- Performance muammosi qanday yuzaga keladi?
- Impure o'rniga qanday yechim bor (computed, signal)?
Yodlash uchun
Impure = har CD'da ishlaydi; faqat zaruratda; performance xavfi bor.
Nima bu?
Angular 14+ da pipe standalone: true bilan NgModule'siz to'g'ridan-to'g'ri komponent imports ga qo'shiladi. Shared module'ga ehtiyoj qolmaydi — tree-shaking yaxshilanadi va import zanjiri soddalashtiriladi.
Kod misoli
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'phoneUz',
standalone: true,
})
export class PhoneUzPipe implements PipeTransform {
transform(value: string | null | undefined): string {
if (!value) return '';
const digits = value.replace(/\D/g, '');
if (digits.length === 12 && digits.startsWith('998')) {
return `+${digits.slice(0, 3)} ${digits.slice(3, 5)} ${digits.slice(5, 8)} ${digits.slice(8, 10)} ${digits.slice(10)}`;
}
if (digits.length === 9) {
return `${digits.slice(0, 2)} ${digits.slice(2, 5)} ${digits.slice(5, 7)} ${digits.slice(7)}`;
}
return value;
}
}
@Component({
selector: 'app-contact',
standalone: true,
imports: [PhoneUzPipe],
template: `
<a [href]="'tel:' + phone">{{ phone | phoneUz }}</a>
`,
})
export class ContactComponent {
phone = '998901234567';
}
Imtihonda
- Standalone pipe vs NgModule declarations?
- Bir pipe bir nechta komponentda qanday share qilinadi?
- Barrel export (index.ts) pattern?
Yodlash uchun
standalone pipe = imports'ga to'g'ridan-to'g'ri; NgModule shart emas.
