Reputation: 405
I have an old @Input
that passes a callback function from the parent component, which I'd like to convert to an input signal.
Using the old decorator input, I can call the passed-in function simply by doing this.callback()
. This of course doesn't work with an input signal because the same statement simply returns the input's value...which in this case is a function, so I would think this.callback()()
would work to get the value of the input (the function) and then actually call the function, but it seems it does not.
If I pass a function to an input signal (currently defined as callback = input.required<() => void>()
), is there a way to actually call the function, or do I just need to stick with the old decorator input for now?
Parent:
@Component({})
class ParentComponent {
parentFunc() {}
}
<app-child-component [callback]="parentFunc" />
Child:
@Component({})
class ChildComponent {
callback = input.required<() => void>();
ngOnInit() {
// doesn't work even though I'd expect it to
this.callback()();
}
}
Upvotes: 1
Views: 63
Reputation: 55669
Make your callback an arrow function instead of a regular method. This way you'll keep the this
context.
@Component({
selector: 'app-root',
imports: [Child],
template: `
<app-child [callback]="callback">
`,
})
export class App {
callback = () => {
console.log('from parent', this.name);
}
}
Upvotes: 1
Reputation: 57986
Make sure you have .bind(this)
to the callback so that it executes on the parent scope.
The callback also should be passed as is, without executing it.
import { Component, input } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
@Component({
selector: 'app-child',
template: `
<button (click)="clickEvent()">click</button>
`,
})
export class Child {
callback = input.required<() => void>();
clickEvent() {
this.callback()();
}
}
@Component({
selector: 'app-root',
imports: [Child],
template: `
<app-child [callback]="callback.bind(this)">
`,
})
export class App {
name = 'Angular';
callback() {
console.log('from parent', this.name);
}
}
bootstrapApplication(App);
Upvotes: 1