
In questo articolo riassumerò alcuni concetti base del framework Angular attraverso un esempio di applicazione Angular completo e funzionante.
Creare una nuova applicazione Angular
Abbiamo già visto come creare una nuova applicazione Angular, daremo all’esempio il nome DemoTextApp, simulando un’applicazione in grado di creare e organizzare messaggi di testo. Scegliamo di utilizzare Angular routing e SCSS come stile.
ng new DemoTextApp
Apriamo l’app creata in Visual Studio Code per poterla modificare.
Utilizzare Angular Material
Per rendere l’interfaccia gradevole faremo uso di Angular Material, che comprende già un allestimento di componenti. Quello che faremo è aggiungere questi componenti ai nostri template facendo riferimento alla documentazione.
Aggiungere il modulo Material
Aggiungiamo Angular Material al progetto scegliendo, tra le opzioni, il tema Indigo/Pink e di usare HammerJS e browser animation.
ng add @angular/material
Creiamo ora un modulo dedicato material attraverso il quale condivideremo i singoli moduli della libreria con i moduli dell’applicazione.
ng g module shared/modules/material --flat=true
Con il comando precedente abbiamo creato il file material.module.ts, indicando con l’opzione –flat di non voler creare un’ulteriore cartella material contenente il modulo ma di inserirlo direttamente all’interno della cartella shared/modules.
nota: tutti i file generati con il comando ng generate .. (abbreviato ng g) verranno inseriti all’interno della cartella app, a meno dell’utilizzo di opzioni – documentazione.
Importiamo il file material.module.ts all’interno di app.module.ts (imports) per poterlo utilizzare, lo modificheremo all’occorrenza.

Aggiungere le pagine principali
Anche se l’app che andremo a creare sarà di modeste dimensioni, per completezza, faremo uso del pattern Lazy Loading. Questo permette il caricamento degli NgModules al loro bisogno, utile appunto per applicazioni di grandi dimensioni con molti percorsi.
Pagina Main
Creiamo subito il modulo e il componente Main come punto di ingresso dell’applicazione, dopodiché creeremo il modulo e il componente Home all’interno del quale andremo a gestire i messaggi.
ng g module main --routing=true
ng g c main
Il primo comando genera all’interno della cartella main il file main.module.ts e, con l’opzione –routing=true, il file main-routing.module.ts automaticamente aggiunto a MainModule come imports. In MainRoutingModule andremo a configurare le rotte che vogliamo utilizzare.
Subito dopo aver eseguito il primo comando possiamo lanciare il secondo, con la quale andremo a creare i componenti per il Main. In automatico verrà aggiunto MainComponent alle dichiarazioni (declarations) di MainModule.


Il modulo Main appena creato ci servirà per gestire le pagine che effettivamente vogliamo andare ad utilizzare, Home e Message. Sembra una cosa un pò macchinosa, ma questo ci permette di svincolarci dall’utilizzare il modulo base app, che invece vogliamo che rimanga il più pulito possibile.
Come prima cosa puliamo il file app.component.html sostituendo il contenuto con l’unica direttiva .
La stessa cosa andremo a fare per il file main.component.html, poiché non ci interessa il contenuto di MainComponent ma piuttosto vogliamo visualizzare i contenuti delle pagine che andrà a gestire.
Creare le pagine Home e Message
Come fatto per Main, andiamo a creare il modulo e i relativi componenti per Home e Message.
ng g module home --routing=true
ng g c home
ng g module message --routing=true
ng g c message
Configurare le rotte per le pagine dell'applicazione Angular
A questo punto dobbiamo configurare il caricamento dei vari moduli definendo il comportamento dell’applicazione.
Il componente Main è il primo che vogliamo caricare all’avvio dell’applicazione. Main deve essere configurato per gestire le pagine Home e Message. Aggiungiamolo alle rotte del modulo AppRouting nel file app-routing.module.ts come in figura.

Successivamente, andiamo a configurare il file main-routing.module.ts definendo le rotte per il caricamento dei moduli Home e Message. In questo esempio, assegneremo alle pagine Home e Message rispettivamente le path “home” e “message”.
Poiché la pagina Home dovrà rappresentare la nostra pagina principale, aggiungiamo un redirect a questa quando la path base “/” viene chiamata.

Ora, dobbiamo configurare le rotte delle pagine affinché queste mostrino il contenuto dei componenti al caricamento del modulo. Modifichiamo le rotte di entrambi, Home e Message, nei corrispettivi file di routing.


Ora puoi testare lo sviluppo fatto fino ad ora: l'avvio dell'applicazione Angular e il corretto caricamento delle pagine Home e Message.
Avvia l'applicazione con il comando ng serve e apriamo l'applicazione in una scheda del browser all'indirizzo http://localhost:4200
Creare un ambiente di Storage per l'applicazione Angular
Poco fa, abbiamo aggiunto e configurato le pagine Home e Message, affinché mostrino il proprio contenuto. In particolare, la pagina message deve mostrare una lista dei messaggi aggiunti.
Da dove prendiamo la lista di messaggi?
Cerchiamo di creare un ambiente di persistenza (nel caso reale di un’applicazione web con architettura RESTful, il compito viene svolto da un back-end) tramite il quale possiamo salvare i messaggi per poi poterli recuperare. Per semplicità, in questo esempio, non useremo un database, ma andremo a salvare i dati direttamente nel browser tramite l’oggetto localStorage.
Andiamo quindi a definire una classe service da utilizzare come interfaccia per la comunicazione con localStorage. Andremo ad inserire uno StoreService all’interno della cartella shared del progetto, dato che questo deve essere condiviso con gli altri componenti, creando una nuova cartella services.
ng g service shared/services/store
Apriamo il file store.service.ts appena creato e implementiamo i metodi che serviranno per salvare e recuperare i dati all’interno dell’oggetto localStorage.

Con il metodo save cosi definito, assumiamo di voler salvare una stringa come tipo di dato. Questo perché l’oggetto localStorage è in grado di gestire esclusivamente stringhe da associare ad una certa chiave come una coppia chiave-valore.
Definire la struttura di un messaggio
Quando parliamo di messaggio, ci riferiamo ad un nuovo oggetto composto da più campi, tra i quali un messaggio di testo.
Creiamo una classe Message come modello di dato definita all’interno di un nuovo file message.ts da posizionare in una nuova cartella model all’interno di shared. Cosi come per il modulo Material, una classe riguardante il modello dei dati deve poter essere condivisa con gli altri componenti.
ng g class shared/model/message

Il nostro tipo di dato sarà composto dai campi:
- id: identificativo dato dal timestamp della creazione
- title: stringa contenente il titolo
- message: stringa contenete il messaggio
- expirationDate: data di scadenza del messaggio
Creare un componente Service di un'applicazione Angular
Un Service in un’applicazione Angular è in genere una classe con uno scopo ristretto e ben definito. Dovrebbe fare qualcosa di specifico e farlo bene.
Nel nostro esempio, creiamo ora una classe MessageService per gestire i messaggi.
ng g service message/message
Apriamo il file message.service.ts e definiamo i metodi che andremo ad utilizzare per la gestione dei messaggi, in particolare:
- save: aggiunge un nuovo messaggio
- getAll: recupera la lista completa
- delete: rimuove un messaggio dalla lista
Definire le pagine dell'applicazione
Arrivati a questo punto, andiamo a comporre le pagine della nostra applicazione Angular utilizzando componenti Material.
La pagina Message
La pagina message dovrà contenere una lista di messaggi e alcuni pulsanti per l’aggiunta e la rimozione di questi dalla lista.
Apriamo il file material.module.ts e importiamo (imports) e esportiamo (exports) il modulo MatListModule per la visualizzazione della lista.
Tutti i nuovi moduli Material che andiamo ad aggiungere devono essere importati (imports) e resi disponibili (esports) all'interno del modulo principale condiviso MaterialModule.
Importiamo il modulo MaterialModule all’interno del modulo MessageModule (dentro imports) per poterlo utilizzare.
Modifichiamo il file message.component.html inserendo il nuovo componente.

La lista viene popolata leggendo la variabile messages$, e facendo uso di AsyncPipe (*ngFor=”let message of messages%%EDITORCONTENT%%nbsp;| async”). Nel caso in cui non sono presenti messaggi viene mostrato il messaggio “No messages yet”.
Dobbiamo inizializzare la variabile all’attivazione del componente e lo facciamo richiamando il metodo getAll di MessageService creato appositamente. Questo metodo, infatti, ha come valore di ritorno un Observable contenente un array di oggetti Message.

Si noti che non è necessario utilizzare .subscribe sull'Observable in quanto AsyncPipe utilizza la direttiva " .. | async ", come si vede in message.component.html.
Una volta completato questo procedimento, si può testare il risultato avviando l'applicazione e andando all'indirizzo http://localhost:4200/message. Ci aspettiamo di visualizzare il messaggio "No messages yet" poiché nessun messaggio è stato ancora inserito.
Definire le operazioni di salvataggio e cancellazione dei messaggi
Procediamo con l’implementazione delle funzionalità della pagina message aggiungendo la possibilità di salvare un nuovo messaggio e cancellarne uno già presente nella lista.
Aggiungere un nuovo messaggio
Solitamente, l’aggiunta di un nuovo oggetto avviene tramite l’inserimento delle informazioni in un form. In questo esempio, per semplicità, creeremo un oggetto standard ogni volta che viene premuto l’apposito pulsante.
Aggiungiamo il metodo add in MessageComponent nel file message.component.ts. Questo si occuperà di passare le informazioni al MessageService che salverà il messaggio nello Storage, e successivamente, ricaricherà la lista (initData).

Aggiungiamo quindi il codice HTML al file message.component.html implementando un pulsante che, al click, andrà a chiamare il metodo precedente passandogli le informazioni.
Modifichiamo l’aspetto della pagina aggiungendo la classe primary-buttons-row, cosi da posizionare i pulsanti specificati all’interno del div nella posizione in basso a destra della schermata. Per questo, apriamo il file message.component.scss e definiamo la classe di stile come nell’immagine sottostante.

Cancellare un messaggio dalla lista
Avendo una rappresentazione a lista, possiamo inserire un pulsante a icona all’interno della riga corrispondente al messaggio. In questo modo abbiamo sufficienti informazioni per identificare un messaggio, come appunto il suo id. Sfruttiamo questa informazione per definire un metodo per la cancellazione dell’elemento.
Entrambi i metodi add e delete, dopo la loro esecuzione (subscribe), devono chiamare il metodo initData, in modo da fare un refresh della lista.
Possiamo ora modificare il template inserendo il pulsante di cancellazione.
Siccome stiamo utilizzando altri componenti Material, quali button e icon, dobbiamo importare i rispettivi moduli in MaterialModule, come visto prima per MatListModule.
Navigare tra le pagine di un'applicazione Angular
La navigazione in un’applicazione Angular è simile alla navigazione in un browser: inserisci un URL nella barra degli indirizzi, oppure, fai click sui collegamenti della pagina e il browser passa a una pagina corrispondente.
Angular Router sfrutta questo modello: può interpretare un URL del browser, eventualmente con parametri, come un’istruzione per passare a una vista associata generata dal client.
Come ultimo step, realizziamo una comunicazione diretta tra le due pagine (Home e Message) aggiungendo altri pulsanti.
Utilizzeremo la direttiva routerLink in tag anchor <a> per la navigazione.
Dalla pagina message vogliamo poter navigare verso la pagina home, e viceversa. Partendo da message, inseriamo il nuovo pulsante dentro il contenitore (primary-buttons-row) definito prima.
Aggiungiamo, come per MessageModule, il modulo MaterialModule tra gli imports di HomeModule, e andiamo a modificare la pagina home.
Creiamo un template adatto inserendo un contenitore in posizione centrale con al suo interno una breve descrizione dell’applicazione e un pulsante per accedere alla lista. Sostituiamo quindi il contenuto di home.component.html come in figura.

Avviando l'applicazione, il risultato che si ottiene per le pagine deve essere come quello mostrato nelle immagini seguenti.
Proviamo il corretto funzionamento premendo i pulsanti nelle pagine.
Sei riuscito a seguirmi fino adesso?
Manca poco, non mollare proprio ora. Tra poco termineremo l’esempio andando a creare un’ulteriore pagina per visualizzare i dettagli del messaggio.
Creare una pagina di dettaglio
Andiamo ora a definire una nuova pagina per la visualizzazione del dettaglio di un messaggio, alla quale si accede facendo click sull’elemento della lista, o meglio, su un nuovo pulsante corrispondente all’elemento della lista.
Creiamo, come visto per le altre pagine, un nuovo modulo MessageDetailsModule e, successivamente, il componenti message-details.
ng g module message-details --routing=true
ng g c message-details
Lasciamo per il momento in sospeso la pagina message-details, e andiamo a creare un’ulteriore pagina message-list. Questo perché andremo ad utilizzare la vecchia pagina message come punto d’ingresso per le varie viste dei messaggi: il dettaglio di un messaggio e la lista. Quest’ultima, è la stessa che abbiamo definito all’interno di message e che la sostituiremo con message-list.
ng g module message-list --routing=true
ng g c message-list
Come appena detto, spostiamo il contenuto di message.component.html nel file message-list.component.html sostituendolo con la sola direttiva . Sostituiamo anche il contenuto di message.component.ts all’interno di message-list.component.ts, affinché la vista si comporti come in precedenza.
Importiamo il modulo MaterialModule in MessageListModule.
Andiamo ora a definire il comportamento delle rotte modificando i file interessati message-routing.module.ts e message-list-routing.module.ts.
A questo punto dovresti provare l'applicazione confrontando con il traguardo precedente: il risultato deve essere equivalente.
Aggiungiamo ora alla lista il pulsante che ci permetterà di accedere alla pagina di dettaglio del messaggio, modificando anche l’aspetto della lista inserendo un divisore tra gli elementi.
Cliccando sul nuovo pulsante vogliamo visualizzare i dettagli del messaggio. Abbiamo inserito la direttiva routerLink al pulsante per permettere la navigazione verso la nuova rotta. Da sottolineare il fatto di aver aggiunto le parentesi quadre ( [routerLink]=”message.id” ) poiché vogliamo passare un valore, l’id del messaggio, come parametro.
Definiamo quindi la nuova rotta aggiornando i file message-routing.module.ts e message-details-routing.module.ts.
La pagina dettaglio di un messaggio
A questo punto non resta che aggiornare il componente message-details per la visualizzazione dei dettagli del messaggio.
Utilizziamo il componente mat-card di Material in modo da rendere la vista più gradevole. Aggiungiamo quindi il modulo MatCardModule tra gli imports e exports del modulo MaterialModule e importiamo quest’ultimo in MessageDetailsModule per poterlo utilizzare.
Modifichiamo il template html in questo modo:

Dobbiamo ora implementare il recupero del messaggio con un metodo da aggiungere alla classe service, per poi renderlo disponibile alla vista.
Creiamo all’interno di MessageService il metodo get che riceve come parametro l’id del messaggio utilizzato per recuperare questo dalla lista.
Implementiamo la classe MessageDetailsComponent per inizializzare la variabile message estraendo l’id passato dalla URL. Per fare questo, utilizzeremo l’oggetto ActivatedRoute di @angular/router.

Per finire, aggiungiamo un pulsante delete tra le azioni disponibili, in modo da poter cancellare il messaggio direttamente dalla sua visualizzazione. Implementiamo anche il metodo delete che esegue l’operazione di cancellazione e riporta alla lista.
Il metodo delete, come lo abbiamo definito, riceve come parametro l’id del messaggio e chiama il metodo delete di MessageService già utilizzato in precedenza. Successivamente, al completamento dell’operazione di cancellazione del messaggio, utilizziamo l’oggetto Router, sempre di @angular/router, per tornare alla pagina della lista.
La pagina risultante sarà quella mostrata in figura.
E ora?
Arrivati a questo punto, l’applicazione è completa e pronta per essere testata nel suo insieme. Apriamo la finestra del browser alla pagina http://localhost:4200 e iniziamo ad usare la nostra applicazione di messaggi.
Spero che quello che hai letto sia stato piacevole e soprattutto utile.
Devo chiederti un favore. Per ringraziarmi del tempo che ho speso e dell’impegno che ho messo nel realizzare l’esempio, puoi condividere questo articolo con altri, per far si che risulti utile anche a loro. È un piccolo sforzo per te e sarebbe veramente grande per me.
Per ringraziarti, ho reso disponibile tutto il codice dell’esempio su GitHub a questo indirizzo, puoi farne tutto l’uso che vorrai.
3 Comments
Grazie a te Alessandro, questo mi permetter? di confrontare per intero il codice con quello che ho riscritto io e allinearmi con l’ottimo tutorial che hai pubblicato.
Buongiorno sono andato a vedere nel GitHub segnalato, ma purtroppo mi sembra che sia stata pubblicata solo la generazione standard di Angular-Cli e non il progetto completo. E’ corretto ?
Buongiorno, hai perfettamente ragione.
Ho aggiornato il repository e ora lo dovresti vedere.
Grazie per il feedback. Ciao