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);