Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Angular’da Dynamic Component Loading

Merhaba,

Bu içeriğimizde Angular mimarisini kullandığımız çeşitli senaryolarda ihtiyaç duyabileceğimiz Dynamic Component Loading işlevinin teknik olarak nasıl gerçekleştirilebileceğini inceliyor olacağız.

Yapısal olarak Angular mimarisi, component’leri selector üzerinden sayfaya gömerek statik bir şekilde kullanabilmemizi yahut route üzerinden eşleşen component’i çağırabilmemizi sağlayan bir işlevselliğe sahiptir. Amma velakin bazen bu doğal işlevselliğin dışında component’leri dinamik olarak bir event neticesinde yükleme ihtiyacı da hissedebiliriz. Bu ihtiyaca istinaden Angular’da ViewContainerRef üzerinden basit bir davranış gerçekleştirmemiz gerekmektedir.

Bu davranış için temelde bir directive ve bir de service olmak üzere iki aktöre ihtiyacımız vardır.

Directive ile dinamik olarak yüklenecek component’i hangi ViewContainerRef içerisine yükleyeceğimizi belirliyor olacağız. Bunun için directive’in aşağıdaki içerikte olması yeterlidir.

import { ViewContainerRef } from '@angular/core';
import { Directive } from '@angular/core';

@Directive({
  selector: '[appLoadComponent]'
})
export class LoadComponentDirective {
  constructor(public viewContainerRef: ViewContainerRef) { }
}

Dikkat ederseniz constructor’ında sadece bir ViewContainerRef almaktadır. Bu parametre, directive ile işaretlenecek olan ng-template objesini yakalayacak ve programatik olarak temsil edecektir.

Service ise dinamik component yükleme işleminin sorumluluğunu üstlenecektir.

import { Injectable, ViewContainerRef } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class LoadComponentService {
  constructor() { }

  async loadComponent(viewContainerRef: ViewContainerRef) {
    const { ExampleComponent } = await import("../example/example.component");

    viewContainerRef.clear();
    let component: any = ExampleComponent;
    return viewContainerRef.createComponent(component);
  }
}

İçeriğine bakarsanız dinamik olarak component yükleme işlemini ‘loadComponent’ metodu ile gerçekleştirmektedir. Bu metot dinamik yükleme işlemi yapılacak olan ng-template nesnesini ViewContainerRef parametresiyle elde etmekte ve createComponent metodu ile component’i oluşturup, yüklemektedir.

Bu inşadan sonra tek yapılması gereken bu aktörleri aşağıdaki gibi kullanmaktır.

app.component.html;

<button (click)="load()">Example Component Load</button>

<br />

<ng-template appLoadComponent>

</ng-template>

Butona tıklandığında ‘ExampleComponent’, ‘appLoadComponent’ isimli directive ile işaretlenmiş olan ng-template‘e dinamik olarak yüklenecektir.

app.component.ts;

import { ViewChild } from '@angular/core';
import { Component } from '@angular/core';
import { LoadComponentDirective } from './directives/load-component.directive';
import { LoadComponentService } from './services/load-component.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  @ViewChild(LoadComponentDirective, { static: true })
  loadComponentDirective: LoadComponentDirective;

  constructor(private loadComponentService: LoadComponentService) {

  }

  load() {
    const containerRef = this.loadComponentDirective.viewContainerRef;
    this.loadComponentService.loadComponent(containerRef)
  }
}

Bunun için 12 – 13. satırlarda bu sayfada/view’de kullanılan LoadComponentDirective elde edilmekte ve içerisindeki ‘viewContainerRef’ ile temsil edilen ng-template objesi, inject edilmiş olan LoadComponentService‘e verilerek dinamik component üretimi gerçekleştirilmektedir.

İşte bu kadar 🙂
Angular'da Dynamic Component Loading

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Not : Örnek çalışmayı aşağıdaki github adresinden edinebilirsiniz.
https://github.com/gncyyldz/Dynamic_Components_Example

Bunlar da hoşunuza gidebilir...

1 Cevap

  1. 06 Aralık 2022

    […] ile yapılan bu manevrayı kullandığımız Angular’da Dynamic Component Loading başlıklı makalemizi ayrı bir örnek olması açısından kaynak olarak […]

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir