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

Custom Structural Directive

### TemplateRef va ViewContainerRef
MiddleSenior

Nima bu?

Structural directive DOM strukturasini o'zgartiradi. TemplateRef — ng-template ichidagi shablon havolasi; ViewContainerRef — shu joyga view (embedded view) yaratish/o'chirish konteyneri. createEmbeddedView() shablonni DOM'ga qo'shadi, clear() olib tashlaydi — *ngIf shu mexanizm asosida ishlaydi.

Kod misoli

import {
  Directive,
  Input,
  TemplateRef,
  ViewContainerRef,
  inject,
} from '@angular/core';

@Directive({
  selector: '[appUnless]',
  standalone: true,
})
export class UnlessDirective {
  private templateRef = inject(TemplateRef<unknown>);
  private vcr = inject(ViewContainerRef);
  private hasView = false;

  @Input() set appUnless(condition: boolean) {
    if (!condition && !this.hasView) {
      this.vcr.createEmbeddedView(this.templateRef);
      this.hasView = true;
    } else if (condition && this.hasView) {
      this.vcr.clear();
      this.hasView = false;
    }
  }
}
<p *appUnless="isHidden">Shart false bo'lsa ko'rinadi (ngIf teskari)</p>
<ng-template [appUnless]="isHidden">
  <p>Property binding usuli ham ishlaydi</p>
</ng-template>
@Component({
  selector: 'app-unless-demo',
  standalone: true,
  imports: [UnlessDirective],
  templateUrl: './unless-demo.component.html',
})
export class UnlessDemoComponent {
  isHidden = false;
}

Muhim nuance: createEmbeddedView chaqirilganda yaratilgan view change detection daraxtida qoladi — vcr.clear() chaqirilmaguncha memory'da turadi, shuning uchun ngOnDestroy'da tozalash yoki hasView kabi flag bilan boshqarish shart (aks holda bir xil view bir necha marta yaratilib, xotira sızishi va DOM dublikati yuzaga keladi).

Imtihonda

  • TemplateRef nima va qayerdan keladi?
  • ViewContainerRef qayerga inject qilinadi?
  • Embedded view vs component view farqi?
  • createEmbeddedView ni shart tekshirmasdan har o'zgarishda chaqirsak nima bo'ladi (dublikat view muammosi)?

Yodlash uchun

Structural = TemplateRef + ViewContainerRef; createEmbeddedView / clear; hasView flag bilan dublikatni oldini ol.

### Microsyntax — * prefiksi
Senior

Nima bu?

* prefiksi (*ngIf="x") Angular microsyntax — qisqa yozuv. U aslida ng-template ga aylantiriladi: [ngIf]="x" property va #ngIf="ngIf" template ref. Custom structural directive ham *appMyDir="expr; param: value" sintaksisini @Input() setter'lar orqali qabul qiladi.

Kod misoli

import {
  Directive,
  Input,
  TemplateRef,
  ViewContainerRef,
  inject,
} from '@angular/core';

interface SelectContext<T> {
  $implicit: T;
  appSelect: T;
  index: number;
}

@Directive({
  selector: '[appSelect]',
  standalone: true,
})
export class SelectDirective<T> {
  private templateRef = inject(TemplateRef<SelectContext<T>>);
  private vcr = inject(ViewContainerRef);

  @Input() set appSelect(source: T[] | null) {
    this.vcr.clear();
    if (!source) return;
    source.forEach((item, index) => {
      this.vcr.createEmbeddedView(this.templateRef, {
        $implicit: item,
        appSelect: item,
        index,
      });
    });
  }
}
<!-- *appSelect="products" desugar qilinganda: -->
<ul>
  <ng-template appSelect let-item let-i="index" [appSelect]="products">
    <li>{{ i + 1 }}. {{ item.name }}</li>
  </ng-template>
</ul>

<!-- Microsyntax qisqa yozuvi (bir xil) -->
<ul>
  <li *appSelect="products; let item; let i = index">
    {{ i + 1 }}. {{ item.name }}
  </li>
</ul>

TypeScript strict template checking (strictTemplates: true) let-itemning tipini SelectContext<T>dan chiqara olmaydi, agar directive static ngTemplateContextGuard metodini e'lon qilmasa. Bu static metod compiler'ga context tipini "isbotlab beradi" — bo'lmasa item any yoki xato tipda qoladi va template ichida type error tutilmaydi.

static ngTemplateContextGuard<T>(
  dir: SelectDirective<T>,
  ctx: unknown
): ctx is SelectContext<T> {
  return true;
}

Imtihonda

  • *ngFor="let x of items" desugar qanday ko'rinishga ega?
  • $implicit va let-x bog'lanishi?
  • Custom microsyntax parametr (let-i="index") qanday ishlaydi?
  • ngTemplateContextGuard nima uchun kerak va bo'lmasa nima yo'qoladi?

Yodlash uchun

*dir = ng-template dir; $implicit = default let-x qiymati; type-safe context uchun ngTemplateContextGuard.

Prev
Custom Attribute Directive
Next
Advanced