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.

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ร