Comprensione di @Input, @Output e EventEmitter in Angular

Per chi è nuovo di Angular, i decoratori Input e Output sono un po’ confusi, specialmente quando li si studia guardando del codice di esempio. In questo articolo, cercherò di spiegarli nel modo più semplice.

Uno strumento per scambiare dati

Prima di tutto, l’idea di Input e Output è di scambiare dati tra componenti. Sono un meccanismo per inviare/ricevere dati da un componente all’altro.

Input è usato per ricevere dati in entrata mentre Output è usato per inviare dati in uscita. Output invia i dati in uscita esponendo i produttori di eventi, di solito gli oggetti EventEmitter.

Quindi quando vedete del codice come questo

@Component({
selector: 'todo-item',
...
})export class TodoItemComponent {
@Input() item
@Output() onChange = new EventEmitter()
}

significa

  • Ehi, sto aspettando che mi vengano inviati dei dati. Li riceverò e li memorizzerò nella mia proprietà item
  • a proposito, produrrò e invierò i dati tramite la proprietà onChange.

Diciamo che avete un componente TodoList che contiene il componente TodoItem. Nel template TodoList, ci si aspetta di vedere

...
<todo-item
="myTask"
(onChange)="handleChange($event)"
</todo-item>
...

che significa

  • TodoList mette i valori dei dati nella sua proprietà myTask e li passa a TodoItem
  • i dati emessi da TodoItem saranno ricevuti e gestiti dalla funzione handleChange() in TodoList

Questa è la teoria. Diamo un’occhiata all’esempio.

@Input e @Output in azione

Guarda questo esempio. Qui ho creato 2 componenti, il componente hello annidato dentro il componente app. Il componente hello ha un Input e un Output

hello.component.ts
@Component({
selector: 'hello',
template: `
<h3 (click)="onClick.emit('Neo')">
...
</h3>
`
})export class HelloComponent {
@Input() myFriend: string
@Output() onClick = new EventEmitter()
}

Si aspetta di ricevere un valore stringa e lo memorizza nella proprietà myFriend.

@Input() myFriend: string

Ogni volta che si clicca su di esso, la proprietà Output onClick emetterà una stringa ‘Neo’ al mondo esterno.

<h3 (click)="onClick.emit('Neo')">

Di seguito c’è il componente app

app.component.ts
export class AppComponent {
ng = 'Angular'
myName = 'Neo' upCase(st:string): void { ... }
}app.component.html
<hello myFriend="{{ ng }}" (onClick)="upCase($event)"></hello>
<h3>My name is {{ myName }}</h3>

Nota che il componente app usa il tag hello nel suo template e fa due cose:

  • passare un valore stringa ‘Angular’ a hello tramite la sua proprietà ng
<hello myFriend="{{ ng }}"
  • ricevere il valore emesso da hello ed elaborare tale valore tramite la funzione upCase()
<hello myFriend="{{ ng }}" (onClick)="upCase($event)">

Puoi vedere l’app in azione qui