1

I am using below code to render my components dynamically -

    @for(item of list(); track $index){
    <!-- dynamic rendering using ng-container -->
    <ng-container *ngComponentOutlet="componentToRender(); inputs: item;" />
}

Is there a way to bind events using any property of ng-container similar to input? I have alreay searched the internet and those solutions suggesting to use @ViewChild but I want to know if any solution exists which uses only templates for event binding.

1 Answer 1

0

Yes, you can pass in the method you want to call as a property and execute the method inside the component code. The property contains the callback, you might lack strict typing, but you can fix this by providing a proper type definition to the input signal.

Parent:

HTML:

@for(item of list(); track $index){
  <!-- dynamic rendering using ng-container -->
  <ng-container *ngComponentOutlet="componentToRender(); inputs: {item, callback: callback.bind(this)};" />
}

TS:

callback(input: string) {
  console.log(this, input, 'child calling parent');
}

Full Code:

import { Component, input, signal, InputSignal } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-child',
  standalone: true,
  template: `
    child: {{item().test}}
    <button (click)="callback()('data from child')">call parent method</button>
  `,
})
export class Child {
  item: InputSignal<any> = input.required();
  callback: InputSignal<(callbackProp: string) => void> = input.required();
}

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [Child, CommonModule],
  template: `
    @for(item of list(); track $index){
      <!-- dynamic rendering using ng-container -->
      <ng-container *ngComponentOutlet="componentToRender(); inputs: {item, callback: callback.bind(this)};" />
    }
  `,
})
export class App {
  name = 'Angular';
  list = signal([{ test: 1 }]);
  componentToRender = signal(Child);

  callback(input: string) {
    console.log(this, input, 'child calling parent');
  }
}

bootstrapApplication(App);

Stackblitz Demo

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.