back to top

Lavorare con le Template Reference Variables in Angular

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.

Pubblicitร 
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.

Esempio applicazione Angular che utilizza una template reference variable

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.

esempio template reference variable

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.

Pubblicitร