Negli ultimi mesi Angular è evoluto rapidamente, introducendo nuove funzionalità e tantissimi miglioramenti, molti dei quali con l’obiettivo di migliorare manutenibilità e prestazioni.
In questo articolo parleremo di una novità introdotta da Angular v17.3.0: la nuova classe HostAttributeToken.
Questa nuova API ci consente di iniettare gli attributi dell’elemento host utilizzando la funzione inject( ), similmente a come funziona il decoratore @Attribute.
Il decoratore @Attribute è forse il decoratore di Angular meno conosciuto.
Dunque, prima di approfondire il funzionamento della classe HostAttributeToken, prendiamoci un momento per rivederlo insieme.
@Attribute: ci serve veramente un input?
Partiamo da uno scenario semplice in cui vogliamo sviluppare un componente in grado di accettare una variabile di configurazione dall’esterno.
Nello specifico, vogliamo fornire questa proprietà come una costante string literal, perché non ci serve aggiornarla a runtime:
<my-divider size="small" />
Code language: HTML, XML (xml)
Non ci serve far altro che creare un input per quella proprietà:
import { Component, Input } from '@angular/core';
export type DividerSize = 'small' | 'big';
@Component({
selector: 'my-divider',
template: '<hr [class]="size" />',
standalone: true,
})
export class MyDivider {
@Input() size: DividerSize;
}
Code language: TypeScript (typescript)
Ben fatto, grazie a questo input il nostro componente riceve il valore di configurazione.
Ma forse è un po troppo…
Creando un input, stiamo chiedendo ad Angular di creare un binding a quella proprietà, e quindi di controllarla durante ogni ciclo di change detection.
Questo è davvero troppo, a noi basta che la proprietà venga controllata solo una volta durante l’inizializzazione del componente. 🤯
Per migliorare le performance possiamo iniettare piuttosto l’attributo host-element nel costruttore grazie al decoratore @Attribute:
import { Attribute, Component } from '@angular/core';
export type DividerSize = 'small' | 'big';
@Component({
selector: 'my-divider',
template: '<hr [class]="size" />',
standalone: true,
})
export class MyDivider {
constructor(@Attribute('size') size: string) {}
}
Code language: TypeScript (typescript)
Usando @Attribute, Angular leggerà il valore solo una volta e mai più.
Nota: questo approccio funziona anche con le Direttive!
Ora che abbiamo rivisto le basi, passiamo all’argomento principale di questo articolo: la nuova classe HostAttributeToken.
Iniettare un attributo utilizzando la classe HostAttributeToken
Dopo il rilascio di Angular 14, esiste ora un nuovo approccio per iniettare i provider senza utilizzare il costruttore: la funzione inject.
Finora, la funzione di inject ci ha permesso di iniettare facilmente componenti, direttive e pipe, ma non vi era modo di iniettare attributi.
Ed è proprio per questo scopo che è stata introdotta la classe HostAttributeToken:
import { Component, HostAttributeToken, inject } from '@angular/core';
export type DividerSize = 'small' | 'big';
@Component({
selector: 'my-divider',
template: '<hr [class]="size" />',
standalone: true,
})
export class MyDivider {
size: string = inject( new HostAttributeToken('size') );
}
Code language: JavaScript (javascript)
Utilizzando classe HostAttributeToken all’interno della funzione inject, possiamo ottenere il valore di un determinato attributo.
Questa nuova API funziona in modo simile a @Attribute, con una notevole differenza: invece di restituire null quando manca l’attributo, solleva un errore.
Questa modifica è stata introdotta per allineare il comportamento a quello degli altri injection token.
Grazie per aver letto questo articolo 🙏
Mi piacerebbe avere qualche feedback quindi grazie in anticipo per qualsiasi commento. 👋
Infine, se ti è piaciuto davvero tanto, condividilo con la tua community. 👋😁