1

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.com/run?file=src%2Fapp%2Fapp.component.ts

PARENT
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: \['./app.component.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>

1 Answer 1

0

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.

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

Stackblitz Demo

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.