
GUIDE PER ASPIRANTI PROGRAMMATORI
I componenti in Angular
Come già detto, i componenti sono il tipo più comune di direttiva che useremo per costruire applicazioni Angular; possiamo definire sinteticamente un componente come una direttiva dotata di un suo tag e di un template HTML. Come una normale direttiva, anche un componente viene legato al DOM tramite un selettore CSS; nel caso dei…


Vuoi avviare una nuova carriera o fare un upgrade?
Trova il corso Digital & Tech più adatto a te nel nostro catalogo!
- Le direttive in Angular
- I componenti in Angular
- Il template in Angular
- Le direttive strutturali in Angular
- La content projection in Angular
- I servizi in Angular
- Le Pipes in Angular
- Routing in Angular
- Invio di form in Angular
- Built-in control flow in Angular
- Deferrable views in Angular
- Image optimization in Angular
Come già detto, i componenti sono il tipo più comune di direttiva che useremo per costruire applicazioni Angular; possiamo definire sinteticamente un componente come una direttiva dotata di un suo tag e di un template HTML.
Come una normale direttiva, anche un componente viene legato al DOM tramite un selettore CSS; nel caso dei componenti il selettore è solitamente un selettore di tag anziché di attributo, per esempio:
@Component({ selector: 'app-component', // <- tag selector // ... }) export class AppComponent { // ... }
Con questo selettore, ogni volta che in un template Angular troverà il tag <app-component /> inizializzerà il componente AppComponent e lo aggancerà al rispettivo nodo del DOM, proiettando il suo template come contenuto del tag.
A differenza di altri framework frontend come React, Angular genera davvero un custom tag con il nome del selettore, e non si limita a sostituirlo con il suo template.
Questo significa che esplorando il DOM nel browser potremo riscontrare tag per tag tutti i componenti che compongono la nostra applicazione!
Come abbiamo anticipato, il contenuto grafico del nostro componente è rappresentato dal suo template HTML. In Angular un template non è altro che un semplice file HTML, ma oltre alla sintassi standard presenta convenzioni per richiamare le direttive o passare valori dinamici, e nelle ultime versioni anche per fare controllo di flusso.
Abbiamo già incontrato un esempio di template HTML in app.component.html, generato automaticamente da ng new e modificato con il nostro esempio sulle direttive; più avanti vedremo dettagliatamente come funziona la template syntax e cosa ci permette di realizzare.
Accanto a selettore e template, la parte attiva di comportamento di un componente è implementata in una classe TypeScript, esattamente come vale per quasi tutti gli elementi di Angular; in questa classe definiremo dipendenze, proprietà e metodi, e collegheremo logicamente queste definizioni alle diverse parti del template attraverso due meccanismi complementari: il data binding (associazione di dati) e l’event binding (associazione di eventi).
Ovviamente approfondiremo tutto a tempo debito, ma torniamo con le mani nel codice per vedere un paio di esempi: abbiamo detto che un componente gestisce una porzione di UI con un comportamento, perciò implementiamo un componente esemplare: un contatore.
Esempio di componente in Angular: il counter.
Iniziamo invocando la CLI:
ng generate component counter
Notiamo subito che la CLI crea automaticamente i componenti in una loro cartella, in modo da poter tenere vicini codice, template e stili, senza mischiarli con quelli di altri componenti.
In genere la CLI creerà per noi anche dei file *.spec.ts usati per fare unit testing; nel corso di questa guida non considereremo questi file.
Andiamo a implementare quello che ci serve lato TypeScript, in counter.component.ts:
import { Component } from '@angular/core'; @Component({ selector: 'app-counter', standalone: true, imports: [], templateUrl: './counter.component.html', styleUrl: './counter.component.css' }) export class CounterComponent { count: number = 0; increment(): void { this.count++ } reset(): void { this.count = 0 } }
In questa semplice classe abbiamo raccolto lo stato del contatore e le due operazioni che potranno essere effettuate sullo stato: incremento e azzeramento.
Vediamo come tutto questo si riflette nel template in counter.component.html:
<h1>Counter</h1> <code>{{ count }}</code> <div> <button (click)="increment()">Increment</button> <button (click)="reset()">Reset</button> </div>
Notiamo subito la sintassi di interpolazione {{ }}, che ci permette di inserire espressioni TypeScript nel nostro codice HTML; in questo caso l’abbiamo fatto per rappresentare il conto del nostro contatore.
L’altra cosa che non siamo abituati a vedere in HTML puro è l’event binding fatto con l’attributo (click); apparentemente questo funziona come l’attributo nativo onclick, ma in realtà si comporta in manierà più sofisticata, agganciando e sganciando dinamicamente l’event handler in base al ciclo di vita del componente, tramite l’API add/removeEventListener.
A questo punto procediamo a richiamare effettivamente il nostro contatore nel template del nostro app.component.html, ma prima importiamolo in app.component.ts:
// ...imports @Component({ selector: 'app-root', standalone: true, imports: [ // ... CounterComponent ], templateUrl: './app.component.html', styleUrl: './app.component.css' }) export class AppComponent { // ... } <app-counter />
Poiché il nostro CounterComponent non riceve dati dal suo componente padre e non ha nodi figli, l’unica cosa che abbiamo dovuto fare per rappresentarlo è inserire il suo tag in forma self closing, che equivale a scrivere <app-counter></app-counter>.
Prima di vedere i template nel dettaglio, rimaniamo un attimo sul nostro contatore per capire come gli stili del linguaggio CSS vengono gestiti da Angular.
Tanto per cominciare, poiché il nodo del template dedicato al componente app-component rappresenta un tag vero e proprio, possiamo stilizzarlo in app.component.css con il suo selettore:
app-counter { display: flex; flex-direction: column; gap: 10px; border: 1px solid gray; border-radius: 10px; padding: 20px; }
Il fatto di poter stilizzare il tag di un componente è già di per sé molto interessante, e possiamo sempre farlo quando vogliamo usare il CSS per regole di collocamento spaziale di un componente, senza doverlo wrappare in un div o simili; tuttavia, delegare lo stile interno di un componente al suo componente padre non è il massimo in termini di separazione delle competenze, perciò possiamo spostare tutte queste regole in counter.component.css, e applicarle al componente usando lo pseudoselettore :host al posto del tag app-counter.
E, già che ci siamo, oltre a questo vediamo di stilizzare un po’ il resto del template:
:host { display: flex; flex-direction: column; gap: 10px; border: 1px solid gray; border-radius: 10px; padding: 20px; } h2 { margin: 0; } div { display: flex; gap: 10px; }
Qui possiamo notare un’altra cosa interessante: non ci siamo preoccupati di introdurre alcun tipo di specificità sui selettori (classi, id, parentela tra gli elementi), e il motivo non è dovuto alla semplicità di questo particolare esempio: il fatto è che non servirebbe.
Se, ad esempio, tornassimo in app.component.html e lo modificassimo come segue:
<app-counter /> <h2>h2</h2> <div>div</div>
noteremmo che né h2 né div (al di fuori di quelli dentro app-counter) sono stati impattati dal CSS che abbiamo scritto in counter.component.css. Questo perché Angular di default incapsula automaticamente tutti gli stili dei componenti, perciò qualsiasi regola scriviamo in un file *.component.css, questa non avrà effetto al di fuori del componente in questione.
Questo meccanismo di isolamento può essere modificato a livello di componente:
@Component({ selector: 'app-counter', standalone: true, imports: [], templateUrl: './counter.component.html', styleUrl: './counter.component.css', encapsulation: ViewEncapsulation.None // <- no view encapsulation })
In ogni caso, tutti i componenti hanno accesso agli stili globalmente definiti in src/styles.css.
È arrivato il momento di procedere, approfondendo i template.
CONTENUTI GRATUITI IN EVIDENZA
Guide per aspiranti programmatori 👨🏻🚀
Vuoi muovere i primi passi nel Digital e Tech? Abbiamo preparato alcune guide per aiutarti a orientarti negli ambiti più richiesti oggi.