I try to share data from Parent to Child and Child to Parent, with variable in template PARENT "mensaje", the template receive this input and show in the input text Child, but when I type other words in the input text child and click to send to Parent it doesnt work in the father, but if I change this variable in template father "mensaje" to "size" it does work. I dont understand why? This example is similar from ponent.ts
PARENT
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './appponent.html',
styleUrls: \['./appponent.scss'\]
})
export class AppComponent {
title = 'Hola Mundo Angular¡';
fontSizePx = "";
mensajePadre=""; //size
}
PARENT
<app-sizer [(mensaje)]="mensajePadre"></app-sizer>
<input id="font-size" [(ngModel)]="mensajePadre"/>
CHILD
export class SizerComponent implements OnInit {
@Input() mensaje: string;
@Output() sizeChange = new EventEmitter<string>();
constructor() { }
ngOnInit(): void {
}
enviarPadre(){
//this.size = Math.min(40, Math.max(8, +this.size ));
this.sizeChange.emit(this.mensaje);
}
}
CHILD
<input type="text" [(ngModel)]="mensaje" name="pixel" #pixel>
<button type="button" (click)="enviarPadre()">Enviar a Padre</button>
I try to share data from Parent to Child and Child to Parent, with variable in template PARENT "mensaje", the template receive this input and show in the input text Child, but when I type other words in the input text child and click to send to Parent it doesnt work in the father, but if I change this variable in template father "mensaje" to "size" it does work. I dont understand why? This example is similar from https://stackblitz/run?file=src%2Fapp%2Fappponent.ts
PARENT
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './appponent.html',
styleUrls: \['./appponent.scss'\]
})
export class AppComponent {
title = 'Hola Mundo Angular¡';
fontSizePx = "";
mensajePadre=""; //size
}
PARENT
<app-sizer [(mensaje)]="mensajePadre"></app-sizer>
<input id="font-size" [(ngModel)]="mensajePadre"/>
CHILD
export class SizerComponent implements OnInit {
@Input() mensaje: string;
@Output() sizeChange = new EventEmitter<string>();
constructor() { }
ngOnInit(): void {
}
enviarPadre(){
//this.size = Math.min(40, Math.max(8, +this.size ));
this.sizeChange.emit(this.mensaje);
}
}
CHILD
<input type="text" [(ngModel)]="mensaje" name="pixel" #pixel>
<button type="button" (click)="enviarPadre()">Enviar a Padre</button>
Share
Improve this question
edited Mar 13 at 7:45
Naren Murali
60.5k5 gold badges44 silver badges78 bronze badges
asked Mar 13 at 7:25
ALEXANDER JOSE TAYPE LUYOALEXANDER JOSE TAYPE LUYO
111 bronze badge
1 Answer
Reset to default 0Signals 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.
Angular Signals - Documentation
@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());
}
}
Stackblitz Demo
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);
}
}
Stackblitz Demo
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);