En este tutorial vamos a aprender cómo cambiar el valor de una variable desde otro componente.
Como desarrolladores es común encontrarnos con la necesidad de manipular datos entre componentes, en este tutorial vamos a aprender cómo cambiar el valor de una variable desde otro componente, no desde un componente padre a hijo (input), si no desde componentes que están al mismo nivel, y para esto debemos usar el EventEmitter, clase que emite eventos personalizados de forma síncrona o asíncrona y los componentes se suscriben a este evento para escuchar los eventos que se disparen a partir de este, así que vamos al código.
Estructura del proyecto: Dos componentes diferentes y desde uno de ellos por medio de un botón, cambiar el valor de la variable del otro componente, en este caso incrementar el valor de la variable.
Para empezar vamos a iniciar creando un proyecto Angular.
ng new angular-change-value-betwen-components
Dentro de la carpeta del proyecto “angular-change-value-betwen-components” vamos a crear dos componentes uno llamado “componente-header” y “componente-home”,
ng generate component component-header
ng generate component component-home
Nos debe quedar de la siguiente manera:
Ahora vamos a modificar los html de los dos componentes que acabamos de crear:
component-header.component.html (ítem es la variable que vamos a cambiar)
<div class="header">
<span>Component header</span>
<button>
Incrementar
</button>
<span style="margin-left: 50px;">{{item}}</span>
</div>
component-home.component.html
<div class="home">
<span>Component Home</span>
<span>{{item}}</span>
</div>
Y ahora en el componente principal en el html vamos a agregar estos dos componentes que acabamos de crear.
app.component.html
<app-component-header></app-component-header>
<app-component-home></app-component-home>
Estos son nuestros componentes recién creados, y el nombre lo sacamos de los archivos ts de cada componente, por ejemplo: En del componente header en el archivo component-header.component.ts el nombre lo tenemos en el selector.
Ahora vamos agregar los estilos para que se vea mejor
Style.css
.header {
padding-left: 20px;
padding-right: 20px;
padding-top: 20px;
height: 100px;
border: 1px solid #ddd;
}
.home {
padding-left: 20px;
padding-right: 20px;
padding-top: 20px;
border: 1px solid #ddd;
height: 300px;
}
Con lo anterior debemos tener la siguiente vista:
Implementando el EventEmitter
Para que dos componentes se comuniquen entre si, es necesario crear un servicio que será el intermediario entre estos dos componentes.
Para agregar el servicio:
ng generate service event-service
event-service.service.ts
Para usar el EventEmitter debemos implementarlo en el import, además del EventEmitter también vamos a importar el Output, quedando de la siguiente forma el servicio.
import { Injectable, Output, EventEmitter } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class EventServiceService {
@Output() item: EventEmitter<boolean> = new EventEmitter();
constructor() { }
changeVariable(variable:boolean) {
this.item.emit(variable);
}
getEmittedValue() {
return this.item;
}
}
Creamos dos métodos uno para cambiar el valor de la variable, método que será llamado desde el componente header y el otro método es para obtener el nuevo valor de la variable, el cual nos suscribiremos desde el componente home.
component-header.component.ts
import { Component, OnInit } from '@angular/core';
import { EventServiceService } from '../event-service.service';
@Component({
selector: 'app-component-header',
templateUrl: './component-header.component.html',
styleUrls: ['./component-header.component.css']
})
export class ComponentHeaderComponent implements OnInit {
item: number = 1;
constructor(private eventServiceService:EventServiceService) { }
ngOnInit() {
}
changeValue() {
this.item++;
this.eventServiceService.changeVariable(this.item);
}
}
Cuando se haga click en el botón incrementar se llama el método changeValue(), y este consumirá el servicio donde tenemos configurado el EventEmitter.
component-home.component.ts
El componente del home dentro del ngOnInit(), nos vamos a suscribir al método getEmittedValue(), de nuestro servicio, con esto quedamos escuchando todo lo que nos emita esta evento.
import { Component, OnInit } from '@angular/core';
import { EventServiceService } from '../event-service.service';
@Component({
selector: 'app-component-home',
templateUrl: './component-home.component.html',
styleUrls: ['./component-home.component.css']
})
export class ComponentHomeComponent implements OnInit {
item: number = 1;
subscription: any;
constructor(private eventServiceService:EventServiceService) { }
ngOnInit() {
this.subscription = this.eventServiceService.getEmittedValue()
.subscribe(item => this.item=item);
}
}
Y en el html del header component (component-header.component.html), agregar el evento click en el botón
<button (click)="changeValue()">
Incrementar
</button>
De esta forma cuando damos click en el botón de incrementar, el método