Detaylı Rehberler
Şablonlar

ng-template ile şablon parçaları oluşturma

Yerel <template> elemanından esinlenen <ng-template> elemanı, dinamik olarak veya programatik olarak işleyebileceğiniz bir şablon parçası -- bir içerik bölümü -- bildirmenize olanak tanır.

Şablon parçası oluşturma

Herhangi bir bileşen şablonu içinde <ng-template> elemanı ile bir şablon parçası oluşturabilirsiniz:

<p>This is a normal element</p>

<ng-template>
  <p>This is a template fragment</p>
</ng-template>

Yukarıdaki işlendiğinde, <ng-template> elemanının içeriği sayfada işlenmez. Bunun yerine, şablon parçasına bir referans alabilir ve onu dinamik olarak işlemek için kod yazabilirsiniz.

Parçalar için bağlam bağlama

Şablon parçaları dinamik ifadeler içeren bağlamalar içerebilir:

@Component({
  /* ... */,
  template: `<ng-template>You've selected {{count}} items.</ng-template>`,
})
export class ItemCounter {
  count: number = 0;
}

Bir şablon parçasındaki ifadeler veya ifade blokları, parçanın nerede işlendiğinden bağımsız olarak, parçanın bildirildiği bileşene göre değerlendirilir.

Şablon parçasına referans alma

Bir şablon parçasına referans almanın üç yolu vardır:

Her üç durumda da parça bir TemplateRef nesnesi ile temsil edilir.

Şablon referans değişkeni ile şablon parçasına referans verme

Aynı şablon dosyasının diğer bölümlerinde o şablon parçasına referans vermek için bir <ng-template> elemanına şablon referans değişkeni ekleyebilirsiniz:

<p>This is a normal element</p>

<ng-template #myFragment>
  <p>This is a template fragment</p>
</ng-template>

Daha sonra bu parçaya şablonun herhangi bir yerinde myFragment değişkeni aracılığıyla referans verebilirsiniz.

Sorgularla şablon parçasına referans verme

Herhangi bir bileşen veya direktif sorgu API'si kullanarak bir şablon parçasına referans alabilirsiniz.

TemplateRef nesnesini doğrudan bir viewChild sorgusu kullanarak sorgulayabilirsiniz.

@Component({
  /* ... */,
  template: `
    <p>This is a normal element</p>

    <ng-template>
      <p>This is a template fragment</p>
    </ng-template>
  `,
})
export class ComponentWithFragment {
  templateRef = viewChild<TemplateRef<unknown>>(TemplateRef);
}

Daha sonra bu parçaya bileşen kodunuzda veya bileşenin şablonunda diğer sınıf üyeleri gibi referans verebilirsiniz.

Bir şablon birden fazla parça içeriyorsa, her <ng-template> elemanına bir şablon referans değişkeni ekleyerek her parçaya bir ad atayabilir ve bu ada göre parçaları sorgulayabilirsiniz:

@Component({
  /* ... */,
  template: `
    <p>This is a normal element</p>

    <ng-template #fragmentOne>
      <p>This is one template fragment</p>
    </ng-template>

    <ng-template #fragmentTwo>
      <p>This is another template fragment</p>
    </ng-template>
  `,
})
export class ComponentWithFragment {
    fragmentOne = viewChild<TemplateRef<unknown>>('fragmentOne');
    fragmentTwo = viewChild<TemplateRef<unknown>>('fragmentTwo');
}

Yine, bu parçalara bileşen kodunuzda veya bileşenin şablonunda diğer sınıf üyeleri gibi referans verebilirsiniz.

Şablon parçasını enjekte etme

Bir direktif, doğrudan bir <ng-template> elemanına uygulanmışsa TemplateRef enjekte edebilir:

@Directive({
  selector: '[myDirective]',
})
export class MyDirective {
  private fragment = inject(TemplateRef);
}
<ng-template myDirective>
  <p>This is one template fragment</p>
</ng-template>

Daha sonra bu parçaya direktif kodunuzda diğer sınıf üyeleri gibi referans verebilirsiniz.

Şablon parçasını işleme

Bir şablon parçasının TemplateRef nesnesine referansınız olduğunda, bir parçayı iki yoldan biriyle işleyebilirsiniz: şablonunuzda NgTemplateOutlet direktifi ile veya TypeScript kodunuzda ViewContainerRef ile.

NgTemplateOutlet kullanma

@angular/common'dan gelen NgTemplateOutlet direktifi bir TemplateRef kabul eder ve parçayı outlet'e sahip elemanın kardeşi olarak işler. NgTemplateOutlet'ı genellikle bir <ng-container> elemanı üzerinde kullanmalısınız.

Öncelikle NgTemplateOutlet'ı içeri aktarın:

import {NgTemplateOutlet} from '@angular/common';

Aşağıdaki örnek, bir şablon parçası bildirir ve bu parçayı NgTemplateOutlet ile bir <ng-container> elemanına işler:

<p>This is a normal element</p>

<ng-template #myFragment>
  <p>This is a fragment</p>
</ng-template>

<ng-container *ngTemplateOutlet="myFragment"></ng-container>

Bu örnek şu işlenmiş DOM'u üretir:

<p>This is a normal element</p>
<p>This is a fragment</p>

ViewContainerRef kullanma

Görünüm kapsayıcısı (view container), Angular'ın bileşen ağacındaki içerik barındırabilecek bir düğümüdür. Herhangi bir bileşen veya direktif, o bileşen veya direktifin DOM'daki konumuna karşılık gelen bir görünüm kapsayıcısına referans almak için ViewContainerRef enjekte edebilir.

Bir şablon parçasını dinamik olarak işlemek için ViewContainerRef üzerindeki createEmbeddedView yöntemini kullanabilirsiniz. Bir parçayı ViewContainerRef ile işlerken, Angular onu ViewContainerRef'i enjekte eden bileşen veya direktifin sonraki kardeşi olarak DOM'a ekler.

Aşağıdaki örnek, bir şablon parçasına referansı giriş olarak kabul eden ve bir buton tıklamasında parçayı DOM'a işleyen bir bileşeni göstermektedir.

@Component({
  /* ... */,
  selector: 'component-with-fragment',
  template: `
    <h2>Component with a fragment</h2>
    <ng-template #myFragment>
      <p>This is the fragment</p>
    </ng-template>
    <my-outlet [fragment]="myFragment" />
  `,
})
export class ComponentWithFragment { }

@Component({
  /* ... */,
  selector: 'my-outlet',
  template: `<button (click)="showFragment()">Show</button>`,
})
export class MyOutlet {
  private viewContainer = inject(ViewContainerRef);
  fragment = input<TemplateRef<unknown> | undefined>();

  showFragment() {
    if (this.fragment()) {
      this.viewContainer.createEmbeddedView(this.fragment());
    }
  }
}

Yukarıdaki örnekte, "Show" butonuna tıklamak şu çıktıyı üretir:

<component-with-fragment>
  <h2>Component with a fragment>
  <my-outlet>
    <button>Show</button>
  </my-outlet>
  <p>This is the fragment</p>
</component-with-fragment>

Şablon parçası işlerken parametre geçirme

<ng-template> ile bir şablon parçası bildirirken, ek olarak parça tarafından kabul edilen parametreler de bildirebilirsiniz. Bir parçayı işlerken, isteğe bağlı olarak bu parametrelere karşılık gelen bir context nesnesi geçebilirsiniz. Bu bağlam nesnesindeki verileri, parçanın bildirildiği bileşendeki verilere referans vermenin yanı sıra, bağlama ifadelerinde ve ifade bloklarında kullanabilirsiniz.

Her parametre, bağlam nesnesindeki bir özellik adıyla eşleşen bir değerle let- öneki ile yazılır:

<ng-template let-pizzaTopping="topping">
  <p>You selected: {{ pizzaTopping }}</p>
</ng-template>

NgTemplateOutlet kullanma

Bir bağlam nesnesini ngTemplateOutletContext girişine bağlayabilirsiniz:

<ng-template #myFragment let-pizzaTopping="topping">
  <p>You selected: {{ pizzaTopping }}</p>
</ng-template>

<ng-container [ngTemplateOutlet]="myFragment" [ngTemplateOutletContext]="{topping: 'onion'}" />

ViewContainerRef kullanma

Bir bağlam nesnesini createEmbeddedView'a ikinci argüman olarak geçebilirsiniz:

this.viewContainer.createEmbeddedView(this.myFragment, {topping: 'onion'});

Şablon parçalarına enjektör sağlama

Bir şablon parçasını işlediğinizde, enjektör bağlamı şablonun bildirim konumundan gelir, işlendiği yerden değil. Özel bir enjektör sağlayarak bu davranışı geçersiz kılabilirsiniz.

NgTemplateOutlet kullanma

ngTemplateOutletInjector girişine özel bir Injector geçebilirsiniz:

export const THEME_DATA = new InjectionToken<string>('THEME_DATA', {
  factory: () => 'light',
});

@Component({
  selector: 'themed-panel',
  template: `<div [class]="theme">...</div>`,
})
export class ThemedPanel {
  theme = inject(THEME_DATA);
}

@Component({
  selector: 'root',
  imports: [NgTemplateOutlet, ThemedPanel],
  template: `
    <ng-template #myFragment>
      <themed-panel />
    </ng-template>
    <ng-container *ngTemplateOutlet="myFragment; injector: customInjector" />
  `,
})
export class Root {
  customInjector = Injector.create({
    providers: [{provide: THEME_DATA, useValue: 'dark'}],
  });
}

Outlet'ın enjektörünü devralma

Gömülü görünümün enjektörünü şablonun bildirildiği yerden değil, outlet'ın DOM'daki konumundan devralmasını sağlamak için ngTemplateOutletInjector'u 'outlet' dizgesine ayarlayabilirsiniz.

<ng-template #node let-items>
  <item-component>
    @for (child of items; track $index) {
      <ng-container
        *ngTemplateOutlet="node; context: {$implicit: child.children}; injector: 'outlet'"
      />
    }
  </item-component>
</ng-template>

<ng-container *ngTemplateOutlet="node; context: {$implicit: topLevelItems}" />

node şablonunun her tekrarlayan işlemesi, çevreleyen <item-component>'ten enjektörü devralır ve her iç içe düzey üst bileşenine kapsamlı sağlayıcılara erişmesine olanak tanır.

NOTE: Bu, özyinelemeli yapılar veya işlenen şablonun outlet sitesindeki bileşen ağacından sağlayıcılara erişmesi gereken herhangi bir durum için faydalıdır.

ViewContainerRef kullanma

createEmbeddedView'daki seçenekler nesnesinin bir parçası olarak özel bir enjektör geçebilirsiniz:

this.viewContainer.createEmbeddedView(this.myFragment, context, {
  injector: myCustomInjector,
});

Yapısal direktifler

Bir yapısal direktif, şu özelliklere sahip herhangi bir direktiftir:

Angular, yapısal direktifler için özel bir kısa yol sözdizimini destekler. Direktifi bir elemana uygularsanız ve direktifin seçicisine yıldız (*) karakteri ile önek eklerseniz, Angular tüm elemanı ve tüm içeriğini bir şablon parçası olarak yorumlar:

<section *myDirective>
  <p>This is a fragment</p>
</section>

Bu, şu ifadeye eşdeğerdir:

<ng-template myDirective>
  <section>
    <p>This is a fragment</p>
  </section>
</ng-template>

Geliştiriciler genellikle parçaları koşullu olarak işlemek veya parçaları birden fazla kez işlemek için yapısal direktifler kullanır.

Daha fazla bilgi için Yapısal Direktifler konusuna bakın.

Ek kaynaklar

ng-template'in diğer kütüphanelerde nasıl kullanıldığına dair örnekler için şu kaynaklara göz atın: