Passaggio di parametri tra Component e ChildComponent tramite @Input()
con alias e @Output
Vediamo un semplice esempio dell’uso di @Input
per passare dei valori dal component principale al component figlio. Questo ci serve per costruire dei componenti riutilizzabili da altri componenti senza dover riscrivere il codice ogni volta. I dati scorreranno dall’alto verso il basso; quando creiamo un component che riceve i dati da un altro componet, dobbiamo dire esplicitamente ad Angular che i dati provengono dall’esterno utilizzando il decoratore @Input
. Basterà posizionare il decoratore @Input
vicino alla variabile del componet figlio a cui si devono “iniettare” i dati che provengono dal componet esterno. Quando si usano dati provenienti da un component esterno, si deve usare un alias in modo da specificare un nome per la proprietà di input (es: @Input('alias')
)Vediamo subito un esempio utilizzando angular-cli per generare il progetto
ng new ex1-components --inline-template --inline-style
ng g interface IBook
ng g component Book --inline-template --inline-style --flat
Con questi tre comandi creiamo il progetto (ex1-components), creiamo l’interfaccia (IBook
) e creiamo la classe (Book). Definiamo l’interfaccia IBook
export interface IBook {
name: string;
author: string;
isbn: string;
}
Ora aggiungiamo al component figlio Book il decoratore @Input
alla variabile theBook
che conterrà ogni singolo elemento passato dal component padre che in questo caso è il nostro root component
import { Component, OnInit, Input } from '@angular/core';
import { IBook } from './ibook';
@Component({
selector: 'app-book',
template: `
<<p>
{{theBook.name}} : {{theBook.author}} : {{theBook.isbn}}
</p>
`,
styles: []
})
export class BookComponent implements OnInit {
@Input('theBook') theBook: IBook;
constructor() { }
ngOnInit() {}
}
Nel component root usiamo il tag <app-book>
iterando tramite la direttiva *ngFor
sull’array dei libri e passando ogni singolo libro al component figlio (book.component) tramite il bind alla variabile theBook
. Quindi ad ogni iterazione passiamo il valore presente in book dell’array books alla variabile theBook
del componente figlio.
import { Component } from '@angular/core';
import { IBook } from './ibook';
@Component({
selector: 'app-root',
template: `
<app-book *ngFor="let book of books" [theBook]="book"></app-book>
`,
styles: []
})
export class AppComponent {
books: Array<IBook> = [
{ name: 'Angular', author: 'tutorial4dev', isbn: 'an6510984'},
{ name: 'Java', author: 'tutorial4dev', isbn: '0j761092'},
{ name: 'Javascript', author: 'tutorial4dev', isbn: '1js7622'}
];
}
Questo esempio è molto semplice proprio per far capire il passaggio di dati tra componete padre e componente figlio
@Output
ed EventEmitter per generare eventi dal componente figlio al componente padre
Ora invece se vogliamo far comunicare il componete figlio con il componete padre dobbiamo fare uso degli eventi in modo da risalire verso l’alto, quindi emettere degli eventi dal basso (componente figlio) verso l’alto (componente padre) e gestirli al livello superiore. Per permettere al componente figlio di emettere un evento verso il componente padre dobbiamo:
- Importare la classe EventEmitter
- Definire un evento personalizzato che il componente figlio emetterà utilizzando l’elemento events della direttiva @Component
- Creare una variabile istanza nella classe con
EventEmitter()
- Chiamare il metodo emit per emettere l’evento
Creiamo una variabile istanza con il decoratore @Output()
di tipo EventEmitter nel componente figlio in modo da emettere eventi quando richiesto, e modifichiamo il padre in modo da associare un attributo evento con lo stesso nome della variabile appena creata nel componente figlio. Angular emetterà un evento dal componete figlio al componente padre che invocherà l’istruzione alla destra dell'evento (click), in questo caso, una funzione che chiama un alert
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { IBook } from './ibook';
@Component({
selector: 'app-book',
template: `
<p>
{{theBook.name}} : {{theBook.author}} : {{theBook.isbn}}
<button (click)="delete(book)">Delete</button>
</p>
`,
styles: []
})
export class BookComponent implements OnInit {
@Input('theBook') theBook: IBook;
@Output() bookDelete = new EventEmitter();
constructor() { }
ngOnInit() {}
delete(book) {
this.bookDelete.emit(book);
}
}
Ora invece predisponiamo il componente padre per ricevere ed elaborare l’evento generato dal componente figlio. Creiamo una funzione deleteBook()
che lancerà un alert e scriverà all'interno il libro selezionato nel componente figlio. Poi settiamo nel template usando le parentesi tonde con il nome dell’evento del componente figlio e dall'altra parte il nome della funzione da chiamare che prende in input il nome del libro dalla lista dei libri.
import { Component } from '@angular/core';
import { IBook } from './ibook';
@Component({
selector: 'app-root',
template: `
<app-book *ngFor="let book of books"
[theBook]="book"
(bookDelete)="deleteBook(book)">
</app-book>
`,
styles: []
})
export class AppComponent {
books: Array<IBook> = [
{ name: 'Angular', author: 'tutorial4dev', isbn: 'an6510984'},
{ name: 'Java', author: 'tutorial4dev', isbn: '0j761092'},
{ name: 'Javascript', author: 'tutorial4dev', isbn: '1js7622'}
];
deleteBook(book: IBook) {
alert('Deleting book:' + JSON.stringify(book));
}
}
Quindi l’applicazione ha una lista di 3 libri, è in ascolto sull'evento bookDelete
che quando si verifica attiva la funzione deleteBook()
del padre. L’evento viene emesso dal figlio alla pressione del button Delete.
Qui il link all'esempio completo: tutorial4dev-angular/ex1-components
Congratulations @clokers! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
You published your First Post
Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Congratulations @clokers! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
You got a First Vote
Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit