Pubblicato il 25/11/2023 da alnao nella categoria Angular & Ionic

Il framework Angular mette a disposizione alcune tecniche per la gestione dei dati nei template, si tratta di tecniche per la gestione della visualizzazione dei dati ma anche tecniche per la gestione dei dati inseriti dall’utente senza l’uso dei form. In questo articolo saranno comprese le tecniche molto usate che non prevedono l’uso dei form e delle variabili, tecniche già esposte in precedenti articoli.

La tecnica più semplice è l’uso del carattere  detto anche Pipe (in inglese traduzione della parola tubo), questa tecnica viene descritta nel sito ufficiale e prevede la definizione di semplici espressioni che accettano un valore in input e ritornano il valore trasformato, sono molto usate perché possono essere usate nei template per trasformare e formattare i dati senza dover modificare il valore originale, un esempio semplice di utilizzo è la formattazione delle date che spesso nei servizi/webService sono nel formato standard json/javascript ma nei template è necessario visualizzarlo nel formato dd/mm/yyyy o simili.

{{valueDate | date: 'dd/MM/yyyy'}}

Le più comuni espressioni pipe previste dal framework sono: DatePipe, UpperCasePipe, LowerCasePipe, CurrencyPipe, DecimalPipe, PercentPipe.

E’ possibile scrivere espressioni personalizzate, per esempio per definire una espressione per eseguire l’esponenziale bisogna definire una classe che implementi il metodo di trasformazione:

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'exponentialStrength'})
export class ExponentialStrengthPipe implements PipeTransform {
  transform(value: number, exponent = 1): number {
    return Math.pow(value, exponent);
  }
}

E poi è possibile usare l’espressione nei template

{{2 | exponentialStrength: 10}}

La documentazione ufficiale mette a disposizione diversi esempi semplici e spiegazioni complete riguardo a questo argomento. L’esempio completo dell’esponenziale infatti è completato nella documentazione ufficiale con l’uso delle variabili è l’uso del ngModel:

@Component({
  selector: 'app-power-boost-calculator',
  template: `
    <h2>Power Boost Calculator</h2>
    <label for="power-input">Normal power: </label>
    <input id="power-input" type="text" [(ngModel)]="power">
    <label for="boost-input">Boost factor: </label>
    <input id="boost-input" type="text" [(ngModel)]="factor">
    <p>
      Super Hero Power: {{power | exponentialStrength: factor}}
    </p>
  `,
  styles: ['input {margin: .5rem 0;}']
})
export class PowerBoostCalculatorComponent {
  power = 5;
  factor = 1;
}

Un’altra applicazione delle pipe è realizzare filtri sugli elenchi nei cicli ngFor, per esempio per filtrare i primi 50 elementi di una lista si può usare la espressione standard slice:

<li *ngFor="let elemento of listaCompleta | slice:0:50 ; let i = index;">
...
</li>

Ma è possibile usare anche slice personalizzare definire da classi specifiche, per esempio per eseguire un filter su una lista si può definre una espressione personalizzata:

@Pipe({ name: 'flyingHeroes' })
export class FlyingHeroesPipe implements PipeTransform {
  transform(allHeroes: Hero[]) {
    return allHeroes.filter(hero => hero.canFly);
  }
}

E nel template si può richiamare la espressione

<li *ngFor="let hero of (heroes | flyingHeroes)">
  {{hero.name}}
</li>

Questa tecnica è usata moltissimo dai programmatori anche per gestire gli oggetti json: in fase di sviluppo è necessario trasformare oggetti json in stringa per visualizzare l’intero oggetto in un template, nativamente Angular non visualizza gli oggetti complessi mentre l’uso del pipe json permette di avere a video la forma completa di un oggetto, la documentazione ufficiale spiega che è usato per convertire un valore nel suo formato json rappresentabile in pagina. L’esempio semplice di questo componente:

@Component({
  selector: 'json-pipe',
  template: `<div>
    <p>Without JSON pipe:</p><pre>{{object}}</pre>
    <p>With JSON pipe:</p><pre>{{object | json}}</pre>
  </div>`
})
export class JsonPipeComponent {
  object: Object = {foo: 'bar', baz: 'qux', nested: 
    {xyz: 3, numbers: [1, 2, 3, 4, 5]}};
}

Il framework mette a disposizione anche il pipe di tipo AsyncPipe che verrà introdotto nell’articolo specifico che palerà della gestione dei servizi e delle funzioni asincrone.

MENU