Custom Attribute Directive
Nima bu?
@Directive dekoratori DOM elementiga xulq-atvor qo'shadigan klass yaratadi (template'siz). selector — atribut, element yoki klass selector; standalone: true — NgModule'siz import qilish. Attribute directive element ko'rinishi/harakatini o'zgartiradi.
Kod misoli
import { Directive, ElementRef, inject, OnInit } from '@angular/core';
@Directive({
selector: '[appHighlight]',
standalone: true,
})
export class HighlightDirective implements OnInit {
private el = inject(ElementRef<HTMLElement>);
ngOnInit(): void {
this.el.nativeElement.style.backgroundColor = '#fef9c3';
this.el.nativeElement.style.padding = '0.25rem';
}
}
@Component({
selector: 'app-demo',
standalone: true,
imports: [HighlightDirective],
template: `
<p appHighlight>Bu matn sariq fon bilan ajratilgan</p>
<p>Bu oddiy matn</p>
`,
})
export class DemoComponent {}
Imtihonda
- Directive vs Component farqi?
- Selector
'[appHighlight]'va'appHighlight'farqi? - Standalone directive qanday import qilinadi?
Yodlash uchun
Directive = template'siz, selector bilan elementga birikadi.
Nima bu?
ElementRef directive biriktirilgan host DOM elementiga nativeElement orqali kirish imkonini beradi. To'g'ridan-to'g'ri DOM manipulyatsiyasi SSR va xavfsizlik nuqtai nazaridan tavsiya etilmaydi — Renderer2 afzal, lekin ElementRef o'qish va oddiy holatlar uchun ishlatiladi.
Kod misoli
import { Directive, ElementRef, inject, Input, OnChanges } from '@angular/core';
@Directive({
selector: '[appAutoFocus]',
standalone: true,
})
export class AutoFocusDirective implements OnChanges {
private el = inject(ElementRef<HTMLInputElement>);
@Input() appAutoFocus = true;
ngOnChanges(): void {
if (this.appAutoFocus) {
setTimeout(() => this.el.nativeElement.focus(), 0);
}
}
}
<input appAutoFocus type="text" placeholder="Avtomatik fokus" />
<input [appAutoFocus]="shouldFocus" type="search" />
Imtihonda
nativeElementserver-side render'da mavjudmi?- ElementRef inject qilish usuli (constructor vs inject())?
- XSS xavfi qachon paydo bo'ladi?
Yodlash uchun
ElementRef = host element; yozish uchun Renderer2 afzal.
Nima bu?
Renderer2 platform-agnostic DOM API — brauzer, server va Web Worker'da xavfsiz ishlaydi. setStyle, addClass, setAttribute, listen kabi metodlar. Angular SSR va universal ilovalarda to'g'ridan-to'g'ri nativeElement o'rniga ishlatiladi.
Kod misoli
import {
Directive,
ElementRef,
Renderer2,
inject,
Input,
OnInit,
OnDestroy,
} from '@angular/core';
@Directive({
selector: '[appTooltip]',
standalone: true,
})
export class TooltipDirective implements OnInit, OnDestroy {
private el = inject(ElementRef);
private renderer = inject(Renderer2);
private unlisten?: () => void;
@Input('appTooltip') text = '';
ngOnInit(): void {
this.renderer.setAttribute(this.el.nativeElement, 'title', this.text);
this.renderer.addClass(this.el.nativeElement, 'has-tooltip');
this.unlisten = this.renderer.listen(
this.el.nativeElement,
'mouseenter',
() => this.renderer.addClass(this.el.nativeElement, 'hover')
);
}
ngOnDestroy(): void {
this.unlisten?.();
}
}
Imtihonda
- Renderer2 vs nativeElement.to'g'ridan-to'g'ri?
Renderer2.listenunsubscribe qanday?- Angular 17+ da Renderer2 hali kerakmi?
Yodlash uchun
SSR uchun Renderer2; listen callback'ni destroy'da tozalash.
Nima bu?
@HostListener directive host elementidagi hodisalarni (click, keydown, mouseenter) tinglaydi. Event nomi va ixtiyoriy argumentlar (['$event'], ['$event.target']) beriladi. Host element template'siz bo'lgani uchun event binding shu orqali amalga oshiriladi.
Kod misoli
import { Directive, HostListener, Input, inject } from '@angular/core';
import { Router } from '@angular/router';
@Directive({
selector: '[appClickOutside]',
standalone: true,
})
export class ClickOutsideDirective {
@Input() appClickOutsideEnabled = true;
private router = inject(Router);
@HostListener('document:click', ['$event'])
onDocumentClick(event: MouseEvent): void {
if (!this.appClickOutsideEnabled) return;
console.log('Document click:', event.target);
}
@HostListener('keydown.enter', ['$event'])
onEnter(event: KeyboardEvent): void {
event.preventDefault();
this.router.navigate(['/search']);
}
@HostListener('mouseenter')
onHover(): void {
console.log('Hover boshlandi');
}
}
Imtihonda
@HostListener('document:click')qanday ishlaydi?$eventargument qanday uzatiladi?- HostListener vs Renderer2.listen farqi?
Yodlash uchun
HostListener = host element eventlari; global event uchun document: prefiksi.
Nima bu?
@HostBinding directive host elementining DOM property'sini (class, style, attr, disabled) klass property'siga bog'laydi. Property o'zgarganda host avtomatik yangilanadi. [class.active]="isActive" kabi, lekin directive ichida.
Kod misoli
import { Directive, HostBinding, HostListener, Input } from '@angular/core';
@Directive({
selector: '[appDropdown]',
standalone: true,
})
export class DropdownDirective {
@Input() disabled = false;
@HostBinding('class.open') isOpen = false;
@HostBinding('class.disabled') get isDisabled(): boolean {
return this.disabled;
}
@HostBinding('attr.aria-expanded') get ariaExpanded(): boolean {
return this.isOpen;
}
@HostListener('click')
toggle(): void {
if (!this.disabled) {
this.isOpen = !this.isOpen;
}
}
}
<button appDropdown [disabled]="isLoading">Menyu</button>
Imtihonda
@HostBinding('class.active')vs@HostBinding('attr.role')?- HostBinding va ngClass birga ishlatiladimi?
- Signal bilan HostBinding ishlatish mumkinmi?
Yodlash uchun
HostBinding = host property/class/attr; o'zgarish avtomatik aks etadi.
Nima bu?
Directive @Input() orqali konfiguratsiya qabul qiladi. Input nomi selector bilan bir xil bo'lishi mumkin: [appHighlight]="color". Alias @Input('appHighlight') yoki @Input({ alias: 'appHighlight' }) bilan beriladi. Bir elementda bir nechta directive ishlashi mumkin.
Kod misoli
import {
Directive,
ElementRef,
Input,
OnChanges,
Renderer2,
inject,
} from '@angular/core';
@Directive({
selector: '[appHighlight]',
standalone: true,
})
export class HighlightDirective implements OnChanges {
private el = inject(ElementRef);
private renderer = inject(Renderer2);
@Input('appHighlight') color = 'yellow';
@Input() highlightPadding = '4px';
ngOnChanges(): void {
this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', this.color);
this.renderer.setStyle(this.el.nativeElement, 'padding', this.highlightPadding);
}
}
<p [appHighlight]="'lightblue'" [highlightPadding]="'8px'">
Input orqali rang berilgan matn
</p>
<p appHighlight>Default sariq rang</p>
Imtihonda
@Input('appHighlight')alias nima uchun?- Directive va Component bir elementda bo'ladimi?
- Input o'zgarganda qaysi hook chaqiriladi?
Yodlash uchun
Directive input = [selectorName]="value"; alias bilan nom moslashtir.
