Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Generare eventi

Come generare eventi in Angular 2 combinando l'utilizzo del decoratore @Output e della classe EventEmitter, passare i dati e definire il payload dell'evento
Come generare eventi in Angular 2 combinando l'utilizzo del decoratore @Output e della classe EventEmitter, passare i dati e definire il payload dell'evento
Link copiato negli appunti

La gestione di eventi generati dall'interazione tra utente e DOM è abbastanza semplice. Come abbiamo visto è sufficiente agire sul template HTML e assegnare al nome dell'evento tra parentesi tonde l'istruzione o la chiamata di funzione che si vuole eseguire.

Eventi personalizzati per i componenti Angular 2

Lo stesso approccio può essere usato per gestire eventi che coinvolgono i nostri componenti. In altre parole, possiamo utilizzare la medesima sintassi non solo per gestire gli eventi standard del DOM, ma anche per gestire eventi personalizzati generati da un nostro componente.

Chiariamo con un esempio ciò che intendiamo dire.

Supponiamo che il nostro componente ArticoloComponent preveda la generazione di un evento like quando un utente clicca sul pulsante per esprimere il proprio apprezzamento. Possiamo sfruttare questo evento per visualizzare un messaggio di ringraziamento nei confronti dell'utente.

Procediamo quindi modificando il template del componente MyAppAppComponent che utilizza il componente ArticoloComponent come mostrato di seguito:

<h1>{{title}}</h1> 
<articolo [articolo]="articolo" (like)="mostraMessaggioRingraziamento()"></articolo>

La funzione mostraMessaggioRingraziamento() dovrà essere implementata come metodo del componente MyAppAppComponent. Un esempio di possibile implementazione potrebbe essere il seguente:

mostraMessaggioRingraziamento() {
	alert("Grazie per aver espresso il tuo apprezzamento per l'articolo!");
}

Per semplicità ci siamo limitati a visualizzare un alert con un messaggio di ringraziamento, ma naturalmente è possibile implementare una soluzione più elaborata.

Il punto ora è: come facciamo a generare un evento personalizzato chiamato like?

Generare un evento, @output e EventEmitter

Angular 2 consente di generare eventi combinando l'utilizzo del decoratore @Output e della classe EventEmitter.

Analogamente a quanto avviene per il decoratore @Input, il decoratore @Output ci consente di definire una proprietà di output, cioè una proprietà che genera un flusso di informazioni dall'interno del componente verso l'esterno. Un evento può essere considerato a tutti gli effetti un meccanismo che abilita flusso di questo tipo.

Come vedremo, al verificarsi di un evento possiamo passare verso l'esterno dati interni al componente, il cosiddetto payload dell'evento. Questo è lo scopo della classe EventEmitter, che ci consente di generare un evento e di passare informazioni all'esterno.

Vediamo come combinare insieme questi elementi analizzando la seguente versione modificata del componente ArticoloComponent:

import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Articolo } from './articolo'
@Component({
	selector: 'articolo',
	templateUrl: 'articolo.component.html',
	styleUrls: ['articolo.component.css']
})
export class ArticoloComponent {
	@Input() articolo: Articolo;
	@Output() like = new EventEmitter<number>();
	constructor() {}
	incrementaApprezzamenti() {
		this.articolo.numApprezzamenti = this.articolo.numApprezzamenti + 1;
		this.like.emit(this.articolo.numApprezzamenti);
	}
}

Rispetto alla versione precedente del componente è utile notare che abbiamo importato Output ed EventEmitter dal modulo @angular/core del framework. Abbiamo quindi definito la proprietà like del componente assegnandole una istanza di EventEmitter:

@Output() like = new EventEmitter<number>();

Come possiamo vedere, abbiamo definito l'istanza di EventEmitter specificando il tipo di dato del payload che l'evento fornirà all'esterno, nel nostro caso il tipo number. Con questo vogliamo indicare che l'evento like metterà a disposizione il numero di apprezzamenti che l'articolo ha ricevuto. L'evento like sarà generato quando l'utente clicca sul pulsante per esprimere il proprio apprezzamento per l'articolo, come mostrato dal seguente codice:

incrementaApprezzamenti() {
	this.articolo.numApprezzamenti = this.articolo.numApprezzamenti + 1;
	this.like.emit(this.articolo.numApprezzamenti);
}

La generazione dell'evento viene effettuata invocando il metodo emit() della proprietà like.

L'effetto finale di questa implementazione sarà dunque la visualizzazione del messaggio di ringranziamento definito in myAppAppComponent ogni volta che un utente esprime il proprio apprezzamento per l'articolo.

Passare dati in un evento

Nella generazione dell'evento like abbiamo passato al metodo emit() il numero di apprezzamenti appena incrementato, rappresentante il payload dell'evento:

incrementaApprezzamenti() {
	this.articolo.numApprezzamenti = this.articolo.numApprezzamenti + 1;
	this.like.emit(this.articolo.numApprezzamenti);
}

Coerentemente alla definizione dell'evento like, abbiamo passato un valore numerico che può essere utilizzato dal gestore del nostro evento. L'utilizzo del payload dell'evento può essere attivato passando l'oggetto $event alla funzione che gestisce l'evento, come mostrato di seguito:

<articolo [articolo]="articolo" (like)="mostraMessaggioRingraziamento($event)"></articolo>

In questo modo, il metodo mostraMessaggioRingraziamento() potrà accedere al numero di apprezzamenti dell'articolo e mostrare, ad esempio, un messaggio più specifico:

mostraMessaggioRingraziamento(numApprezzamenti) {
	alert("Grazie per aver espresso il tuo apprezzamento per l'articolo! \n Il numero di apprezzamenti raggiunti è ${numApprezzamenti}");
}

In linea di massima, è opportuno strutturare il payload dell'evento in un oggetto, come mostrato nel seguente esempio:

import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Articolo } from './articolo'
@Component({
	selector: 'articolo',
	templateUrl: 'articolo.component.html',
	styleUrls: ['articolo.component.css']
})
export class ArticoloComponent {
	@Input() articolo: Articolo;
	@Output() like = new EventEmitter();
	constructor() {}
	incrementaApprezzamenti() {
		this.articolo.numApprezzamenti = this.articolo.numApprezzamenti + 1;
		this.like.emit({numApprezzamenti: this.articolo.numApprezzamenti});
	}
}

In questa ridefinizione del componente ArticoloComponent abbiamo dichiarato che il payload del nostro evento sarà costituito da un oggetto con una proprietà di tipo numerico numApprezzamenti. In effetti, il parametro che passiamo al metodo emit() è un oggetto con la struttura dichiarata.

Il gestore del nostro evento like dovrà essere modificato quindi come segue:

mostraMessaggioRingraziamento(event) {
	alert("Grazie per aver espresso il tuo apprezzamento per l'articolo! \n Il numero di apprezzamenti raggiunti è ${event.numApprezzamenti}");
}

Oltre ad essere necessario quando si debbono passare più informazioni, questo approccio consente di affrontare in maniera più efficace l'eventuale evoluzione della struttura dei dati da inviare verso l'esterno. Infatti, se abbiamo necessità di passare una nuova informazione è sufficiente aggiungere una proprietà all'oggetto che rappresenta il payload dell'evento.


Ti consigliamo anche