Angular Dynamic Components

ரன்டைம் கூறுகளை உருவாக்கவும் கற்றுக்கொள்ளுங்கள்

Angular Dynamic Components

createComponent() மூலம் ரன்டைமில் கூறுகளை உருவாக்கவும், அல்லது selector இல்லாத standalone கூறுகளை *ngComponentOutlet மூலம் வழங்கவும்.

Dynamic Components Essentials

createComponent(): ரன்டைமில் கூறுகளை உருவாக்கவும் மற்றும் உள்ளீடுகள், வெளியீடுகள் மற்றும் directives-ஐ நேரடியாக அனுப்பவும்.

Selectorless components: Standalone கூறுகளை selector இல்லாமல் *ngComponentOutlet மூலம் பயன்படுத்தலாம்.

Signals: signal() இருந்து மாறும் நிலையை இயக்கவும் மற்றும் டெம்ப்ளேட்டுகளில் signal-ஐ அழைப்பதன் மூலம் படிக்கவும்.

💡Jassif Team Notes:

Control Flow for @if/@for, மற்றும் Signals for state and effects பற்றி காண்க.

எளிய outlets-க்கு selectorless + *ngComponentOutlet-ஐ விரும்பவும்; நுணுக்கமான கட்டுப்பாட்டிற்கு createComponent() பயன்படுத்தவும் (host உறுப்பு, directives, lifecycle).

createComponent() with Inputs & Outputs

உள்ளீடுகள்/வெளியீடுகளை வழங்கவும் மற்றும் DOM-இல் இணைக்க ஒரு விருப்பமான hostElement.

கூறு வழங்குநர்களைத் தீர்க்கக்கூடியதாக EnvironmentInjector (அல்லது inject()) பயன்படுத்தவும்.

Complete Example

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, EventEmitter, Output, Input, ElementRef, ViewChild, inject, EnvironmentInjector, ComponentRef } from '@angular/core';
import { createComponent } from '@angular/core';

@Component({
  standalone: true,
  template: `
    <div style="padding:8px;border:1px solid #ddd;border-radius:6px;">
      <h4 style="margin:0 0 8px 0;">{{ title }}</h4>
      <button (click)="clicked.emit()">Click</button>
    </div>
  `
})
export class Card {
  @Input() title = 'Card';
  @Output() clicked = new EventEmitter<void>();
}

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <h3>Dynamic createComponent()</h3>
    <div #host style="min-height:60px;border:1px dashed #aaa;padding:8px;border-radius:6px;"></div>
    <div style="margin-top:8px;display:flex;gap:8px;flex-wrap:wrap;">
      <button (click)="mount()">Mount</button>
      <button (click)="update()">Update input</button>
      <button (click)="unmount()">Unmount</button>
    </div>
  `
})
export class App {
  @ViewChild('host', { read: ElementRef }) host!: ElementRef<HTMLElement>;
  env: EnvironmentInjector = inject(EnvironmentInjector);
  ref: ComponentRef<Card> | null = null;

  mount() {
    if (this.ref) return;
    this.ref = createComponent(Card, {
      environmentInjector: this.env,
      hostElement: this.host.nativeElement
    });
    this.ref.setInput?.('title', 'Hello from Dynamic');
    this.ref.instance.clicked.subscribe(() => alert('Card clicked'));
  }
  update() {
    if (!this.ref) return;
    this.ref.setInput?.('title', 'Updated Title ' + new Date().toLocaleTimeString());
  }
  unmount() {
    this.ref?.destroy();
    this.ref = null;
  }
}

bootstrapApplication(App);

🔍Example Explained:

createComponent(Card, ...): ரன்டைமில் Card கூறை உருவாக்குகிறது மற்றும் ஒரு கூறு ref-ஐ வழங்குகிறது.

environmentInjector: மாறும் கூறு வழங்குநர்களைத் தீர்க்கக்கூடியதாக DI-ஐ வழங்குகிறது.

hostElement: கூறின் host-ஐ கொடுக்கப்பட்ட DOM உறுப்பில் (#host) இணைக்கிறது.

inputs/outputs: ஆரம்ப உள்ளீடுகளை அமைக்கிறது மற்றும் வெளியீடு callback-களை இணைக்கிறது (எ.கா., clicked).

setInput / destroy: பின்னர் உள்ளீடுகளை புதுப்பிக்க ref.setInput(...) மூலம் மற்றும் ref.destroy() மூலம் சுத்தம் செய்யவும்.

Important Notes:

Cleanup: அகற்றும்போது எப்போதும் கூறு ref-இல் destroy() அழைக்கவும்.

Updating inputs: புதிய உள்ளீடு மதிப்புகளை தள்ள கூறு ref-இல் setInput(name, value) பயன்படுத்தவும்.

Selectorless via *ngComponentOutlet

*ngComponentOutlet ஐப் பயன்படுத்தி selector இல்லாமல் ஒரு standalone கூறை வழங்கவும்.

உள்ளீடுகள் மற்றும் வெளியீடுகளை outlet micro-syntax-இல் inline-ஆக அனுப்பவும்.

Example

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, EventEmitter, Output, Input, signal } from '@angular/core';
import { NgComponentOutlet } from '@angular/common';

@Component({
  standalone: true,
  template: `<button (click)="clicked.emit()">{{ label }}</button>`
})
export class ActionButton {
  @Input() label = 'Do it';
  @Output() clicked = new EventEmitter<void>();
}

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [NgComponentOutlet],
  template: `
    <h3>Selectorless via *ngComponentOutlet</h3>
    <p>Clicks: {{ clicks() }}</p>
    <ng-container *ngComponentOutlet="ActionButton; inputs: { label: 'Launch' }; outputs: { clicked: onClick }"></ng-container>
  `
})
export class App {
  ActionButton = ActionButton;
  clicks = signal(0);
  onClick = () => this.clicks.update(n => n + 1);
}

bootstrapApplication(App);

🔍Example Explained:

*ngComponentOutlet="ActionButton": ActionButton மூலம் குறிப்பிடப்பட்ட standalone கூறு வகுப்பை வழங்குகிறது.

inputs / outputs: outlet micro-syntax-இல் மதிப்புகள் மற்றும் நிகழ்வு கையாளிகளை நேரடியாக அனுப்பவும்.

Signals for state: clicks signal நிலையை வைத்திருக்கிறது மற்றும் onClick அதிகரிக்கும் போது UI-ஐப் புதுப்பிக்கிறது.

🔄Notes:

Inputs/Outputs: outlet micro-syntax எளிதான இணைப்புக்கான உள்ளீடுகள் மற்றும் வெளியீடுகள் பைகளை ஆதரிக்கிறது.

Composition: நிபந்தனை அல்லது மீண்டும் மீண்டும் மாறும் UI-க்கு @if/@for உள்ளே outlets பயன்படுத்தவும்.

Dynamic Component Approaches Comparison

Feature createComponent() *ngComponentOutlet
Control Level High (full lifecycle control) Medium (template-driven)
Host Element Customizable Automatic (ng-container)
Input Updates setInput() method Template binding
Cleanup Manual destroy() call Automatic with view destruction
Use Case Complex dynamic UIs Simple component outlets
Performance More control over performance Optimized by Angular

Dynamic Components Quiz

Which API creates a component dynamically at runtime?

bootstrapApplication()
✗ Incorrect! bootstrapApplication() bootstraps the main app, doesn't create dynamic components
provideRouter()
✗ Incorrect! provideRouter() configures routing, not dynamic components
createComponent()
✓ Correct! createComponent() is the API for creating components dynamically at runtime
அடுத்தது