With the traditional @Input() decorator, one can use the ngChanges to do something if the value change. In this case, I'm using a component in the ng-bootstrap modal. The modal contains a form. When the item to edit is selected, it's passed to the component that's in the modal.
@Input() inputVar!: SomeType;
ngOnChanges(changes: SimpleChanges): void {
const chInputVar = changes['inputVar'];
//Do something when the value changes...
}
Now, I'd like to use the signal input:
inputVar = input<SomeType>();
//How to act when the value changes?
ngOnChanges
fires for all input changes. Instead go for effect which fires only when the signals inside the effect.
@Component({
selector: 'app-child',
standalone: true,
template: ``,
})
export class Child {
inputVar = input<number>();
constructor() {
effect(() => {
const value = this.inputVar();
console.log('signal change', value);
// Perform the signal change logic here!
});
}
}
If you must use ngOnChanges
then below is a working example for the same.
import { Component, effect, input, SimpleChanges } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
@Component({
selector: 'app-child',
standalone: true,
template: ``,
})
export class Child {
inputVar = input<number>();
constructor() {}
ngOnChanges(changes: SimpleChanges) {
console.log(changes);
const inputVar = changes?.['inputVar'];
if (inputVar?.currentValue !== inputVar?.previousValue) {
console.log('change', inputVar);
}
}
}
@Component({
selector: 'app-root',
standalone: true,
imports: [Child],
template: `
<app-child [inputVar]="value" />
`,
})
export class App {
value = 0;
ngOnInit() {
setInterval(() => {
this.value = Math.random();
}, 1000);
}
}
bootstrapApplication(App);