Signals Implementation:
If you are using latest angular version consider using model signal (used for two way data binding between parent and child), then use linkedSignal to create a local state (derived from model but can be modified - local state), on button click, we simply sync the local state to the model signal.
@Component({
selector: 'app-sizer',
imports: [FormsModule],
template: `
<input type="text" [(ngModel)]="mensajeLocalState" name="pixel" #pixel>
<button type="button" (click)="enviarPadre()">Enviar a Padre</button>
`,
})
export class SizerComponent {
mensaje = model('');
// local state
mensajeLocalState = linkedSignal(() =>
this.mensaje()
);
enviarPadre() {
//this.size = Math.min(40, Math.max(8, +this.size ));
this.mensaje.set(this.mensajeLocalState());
}
}
Angular @Input @Output implementation:
When doing two way binding, the @Input name mensaje should be the same as the @Output with the prefix Change appended to it.
So it should be:
export class SizerComponent implements OnInit {
@Input() mensaje!: string;
@Output() mensajeChange = new EventEmitter<string>();
constructor() {}
ngOnInit(): void {}
enviarPadre() {
//this.size = Math.min(40, Math.max(8, +this.size ));
this.mensajeChange.emit(this.mensaje);
}
}
Or you can use the alias string inside the @Input and @Output to give different names compared to the binding.
export class SizerComponent implements OnInit {
@Input() mensaje!: string;
@Output('mensajeChange') sizeChange = new EventEmitter<string>(); // <- alias
constructor() {}
ngOnInit(): void {}
enviarPadre() {
//this.size = Math.min(40, Math.max(8, +this.size ));
this.sizeChange.emit(this.mensaje);
}
}
Full Code:
import { Component, EventEmitter, Input, Output, OnInit } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-sizer',
imports: [FormsModule],
template: `
<input type="text" [(ngModel)]="mensaje" name="pixel" #pixel>
<button type="button" (click)="enviarPadre()">Enviar a Padre</button>
`,
})
export class SizerComponent implements OnInit {
@Input() mensaje!: string;
@Output() mensajeChange = new EventEmitter<string>();
constructor() {}
ngOnInit(): void {}
enviarPadre() {
//this.size = Math.min(40, Math.max(8, +this.size ));
this.mensajeChange.emit(this.mensaje);
}
}
@Component({
selector: 'app-root',
imports: [FormsModule, SizerComponent],
template: `
<app-sizer [(mensaje)]="mensajePadre"></app-sizer>
<input id="font-size" [(ngModel)]="mensajePadre"/>
`,
})
export class App {
title = 'Hola Mundo Angular¡';
fontSizePx = '';
mensajePadre = ''; //size
}
bootstrapApplication(App);