Dopo una leggera deviazione che ci ha permesso di illustrare qual รจ il ciclo di vita di un componente, torniamo a rivolgere nuovamente la nostra attenzione ai template dei componenti ed esploriamo una nuova funzionalitร che risulta molto spesso utile. Stiamo parlando delle cosiddette Template reference variables che inizieremo a scoprire in questa lezione attraverso dei semplici esempi.
Una Template reference variable consente di usare allโinterno del template una specie di identificatore che contiene un riferimento ad un elemento del DOM, ad un componente o ad una direttiva (come vedremo quando parleremo dei form in Angular) in modo da poter accedere al loro valore o proprietร in altre parti del template.
import { Component } from '@angular/core';
@Component({
selector: 'simple-root',
template: `
<input type="text" placeholder="Inserisci il valore in euro" #money>
<!-- accediamo al valore del campo input attraverso -->
<!-- la Template reference variable #money -->
<button (click)="convert(money.value)">Converti</button>
<br>
{{ usd | currency }}
`
})
export class AppComponent {
private conversionRate = 1.1379;
usd = 0;
convert(value: string) {
this.usd = parseFloat(value) * this.conversionRate;
}
}
La sintassi per definire una Template reference variable prevede lโuso del carattere โ#โ seguito dal nome che utilizziamo in seguito per accedere al valore conservato nella variabile. Per esempio, nel frammento di codice riportato sopra, abbiamo una variabile โ#moneyโ presente sullโelemento <input>
che mantiene un riferimento a questโultimo e permette di recuperare successiavamente il suo valore (money.value) che viene passato al metodo convert(). In questo modo, ogni volta che viene premuto il pulsante โConvertiโ, viene prelevato il valore corrente del campo <input>
proprio attraverso la variabile โ#moneyโ.
Questoe variabili hanno visibilitร limitata al template in cui vengono definite, per cui allโinterno del template di un componente รจ bene accertarsi di non usare lo stesso nome per due diverse Template reference variable.
Ovviamente รจ possibile usare le Template reference variable anche per i componenti da noi definiti come mostrato nellโesempio sottostante.
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'simple-car-details',
template: `
<h1>{{ car.model }}</h1>
<h2>Dettagli</h2>
<ul>
<li>Colore: {{ car.color }}</li>
<li>Anno: {{ car.anno }}</li>
</ul>
`
})
export class CarDetailsComponent {
car = {
model: 'Bmw Z8 Roadster',
color: 'grigio',
anno: 2002
};
}
Abbiamo definito un componente CarDetailsComponent che andiamo poi ad utilizzare allโinterno del template del componente AppComponent.
import { Component } from '@angular/core';
@Component({
selector: 'simple-root',
template: `
<simple-car-details #car></simple-car-details>
<a href="#">Acquista ora una {{ car.car.model }}</a>
`
})
export class AppComponent {}
Grazie alla Template Reference variable โ#carโ accediamo alle informazioni contenute nel componente AppComponent, in particolare recuperiamo il valore della proprietร model dellโoggetto car del componente AppComponent.
Una Template Reference variable rappresenta anche un metodo alternativo per ottenere il valore di un campo di <input>
man mano che viene digitato qualcosa al suo interno invece di utilizzare la tecnica del two way data-binding o la combinazione di binding di una proprietร e binding di un evento con conseguente accesso allโoggetto $event messo a disposizione da Angular.
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'simple-input',
template: `
<input #field (keyup)="0">
<p>{{field.value}}</p>
`
})
export class InputComponent { }
Allโinterno del frammento di codice mostrato sopra abbiamo intercettato lโevento keyup e abbiamo associato semplicemente il numero zero, ovvero unโespressione che di per sรฉ non fa nulla se non segnalare ad Angular di aggiornare il componente in seguito alla digitazione di un nuovo carattere. Angular avvia infatti il meccanismo di aggiornamento del componente solo in risposta ad eventi asincroni come avviene in questo caso per lโevento keyup.
Per identificare una Template Reference variables, in alternativa allโuso del simbolo โ#โ, possiamo impiegare la sintassi piรน estesa che prevede lโutilizzo del prefisso โref-โ al posto del simbolo โ#โ. Facendo riferimento allโesempio appena visto, possiamo modificare il template del componente InputComponent come segue.
<input ref-field (keyup)="0">
<p>{{field.value}}</p>
In precedenza abbiamo affermato che possiamo utilizzare le Template Reference variable solo nel template. Ma, se abbiamo necessitร di far riferimento a un certo elemento direttamente allโinterno del componente, possiamo affidarci al decoratore @ViewChild.
Modifichiamo quindi il primo esempio esaminato in questa lezione utilizzando proprio il decoratore @ViewChild per recuperare il valore corrente presente nel campo di input. In questo caso inseriamo anche il tasso di conversione nel template e accediamo al suo valore allโinterno del metodo convert() dopo aver ottenuto un riferimento allโelemento che lo contiene sempre grazie al decoratore @ViewChild.
import { Component, ViewChild, ElementRef } from '@angular/core'; // 1
@Component({
selector: 'simple-root',
template: `
<!-- 2: Applichiamo #eur -->
<input type="text" placeholder="Inserisci il valore in euro" #eur>
<button (click)="convert()">Converti</button>
<!-- 3: Applichiamo #conversionRate -->
<p>Tasso di conversione EUR/USD <span #conversionRate>1.1379</span></p>
<br>
{{ usd | currency }}
`
})
export class AppComponent {
// 4 Utilizziamo il decoratore @ViewChild
@ViewChild('eur') eurInputField: ElementRef;
@ViewChild('conversionRate') conversionRate: ElementRef;
usd = 0;
convert() {
const eur = parseFloat(this.eurInputField.nativeElement.value);
const conversionRate =
parseFloat(this.conversionRate.nativeElement.textContent);
if (eur) {
this.usd = eur * conversionRate;
}
}
}
Passiamo al decoratore @ViewChild una stringa come argomento che coincide col nome della Template Reference Variable applicata a un certo elemento nel template. Otteniamo cosรฌ due oggetti di tipo ElementRef (eurInputField e conversionRate) che costituiscono un wrapper intorno allโelemento nativo. Infine nel momento in cui premiamo il pulsante โConvertiโ, invochiamo il metodo convert() che permette di calcolare il nuovo valore in dollari.
Riepilogo
In questa lezione abbiamo visto cosa sono e come utilizzare le Template Reference variables che contengono un riferimento ad un elemento del DOM, ad un componente o ad una direttiva in modo da poter ottenere il loro valore o una qualsiasi proprietร in altre parti del template. Abbiamo inotre illustrato un esempio in cui abbiamo combinato lโuso di una Template Reference variable con il decoratore @ViewChild per accedere ad un elemento del template allโinterno della classe che definisce il componente.