Creare una web application con Spring Boot, MongoDB, Angular 4 e TypeScript e deployarla in cloud come Microsoft Azure Webapp – Parte 4

Qui la parte precedente dell’articolo: Creare una web application con Spring Boot, MongoDB, Angular 4 e TypeScript e deployarla in cloud come Microsoft Azure Webapp – Parte 3

Procediamo ora analizzando, con un esempio, alcuni dei meccanismi base di Angular.

Creeremo infatti:

  • una classe TypeScript che costituirà il Model di un’entità User
  • un Component per renderizzare gli oggetti della classe User
  • un array di User all’interno della definizione della root application
  • una tabella all’interno del Template della root Application in cui saranno mostrati gli utenti

Creazione di una classe TypeScript

Iniziamo creando una nuova cartella all’interno della root application “app”. Cliccando su di essa con il tasto destro del mouse, selezioniamo poi “New” -> “Folder” e chiamiamo la nuova cartella “models”. All’interno di questa nuova cartella creiamo la nostra classe TypeScript. Clicchiamo quindi ancora con il tasto destro su “models” e selezioniamo “New”, scegliendo poi questa volta la voce “Class” del menù, come illustrato in figura
26 - Spring Boot and Angular4 create a new TypeScript class
Chiamiamo la nostra classe “User” e, lasciando l’impostazione di default, essa sarà creata sul relativo file TypeScript chiamato “user.ts”. La classe inizialmente è vuota e il contenuto del file è semplicemente il seguente:

export class User {

}

27 - Spring Boot and Angular4 create a new TypeScript class
Con un tipico approccio object-oriented inseriamo nella classe le proprietà che vogliamo definire per la nostra entità e un costruttore per la creazione di istanze della classe. Grazie a TypeScript, come sappiamo, abbiamo la possibilità di definire staticamente i tipi delle variabili d’istanza.

In un primo momento utilizziamo un approccio standard per la definizione di variabili di istanza e costruttore, poi vediamo invece un modo molto più sintetico che TypeScript ci mette a disposizione.

Ad esempio, supponiamo di voler definire per la nostra classe le seguenti proprietà e relativo tipo:

  • firstname -> stringa
  • lastname -> stringa
  • country -> stringa
  • age -> numero intero

Per farlo, in TypeScript, dobbiamo modificare la classe User come segue:

export class User {

  firstname: string;
  lastname: string;
  country: string;
  age: number;

}

Per creare il costruttore il codice sarà invece il seguente:

  constructor(firstname: string, lastname: string, country: string, age: number) {
    this.firstname = firstname;
    this.lastname = lastname;
    this.country = country
    this.age = age;
  }

Quindi il codice completo della classe User, per il momento, diventa:

export class User {

  firstname: string;
  lastname: string;
  country: string;
  age: number;

  constructor(firstname: string, lastname: string, country: string, age: number) {
    this.firstname = firstname;
    this.lastname = lastname;
    this.country = country
    this.age = age;
  }
}

Come accennato brevemente poco fa, però, TypeScript ci offre un modo alternativo e più conciso di esprimere la stessa cosa, che ci permette di evitare di indicare esplicitamente sia la definizione delle variabili di istanza che la loro assegnazione all’interno del costruttore.

Questo si ottiene includendo la definizione delle variabili d’istanza con il loro modificatore di visibilità direttamente nei parametri del costruttore.

Il default, quando le variabili d’istanza non hanno nessun modificatore di visibilità esplicitato, è “public”. Quindi, specificando il modificatore public prima delle variabili passate come parametri al costruttore, possiamo evitare di specificare gli assegnamenti all’interno del costruttore stesso, oltre che a dichiarare le variabili.

In sostanza, la nostra classe si riduce ad un’unica riga di codice:

export class User {

  constructor(public firstname: string, public lastname: string, public country: string, public age: number) {

  }
}

28 - Spring Tool Suite and Angular4 TypeScript class short constructor
Da notare che questa sintassi sostituisce in toto la definizione e valorizzazione delle variabili; se infatti lasciamo sia la dichiarazione “classica” delle variabili che il modificatore di visibilità prima dei parametri del costruttore, otteniamo un errore di duplicazione delle proprietà della classe.
29 - Spring Tool Suite and Angular4 TypeScript class constructor duplicate keys

Creazione di un Component Angular

Ora che abbiamo definito la classe del nostro model, dobbiamo creare un Component che utilizzeremo per renderizzare in pagina i suoi oggetti.

Al solito, facciamo click con il tasto destro su “app”, poi selezioniamo “New” e questa volta scegliamo dal menù la voce “Component”.
30 - Spring Boot and Angular4 create a new Angular Component

Si apre quindi il wizard di creazione che ci permette di scegliere il nome dell’elemento con il componente verrà renderizzato in HTML. Qui, prestiamo un attimo attenzione alla relazione tra il nome della classe che costituisce il componente e il nome dell’elemento HTML che dovremo utilizzare per renderizzare in pagina il template del componente stesso:

  • Per il nome del Component viene utilizzato il Camel Case con l’iniziale maiuscola
  • Il nome dell’elemento HTML viene convertito nel formato hyphen-separated, cioè separato dal trattino (spesso chiamato anche “kebab-case” per il fatto che le varie parole sembrano infilzate). Il trattino viene inserito per ogni maiuscola del camel case del nome del component (prima di Details quindi)
  • Il suffisso Component non viene riportato nel nome dell’elemento

Il wizard di Spring Tool Suite ci permette di scegliere il nome dell’elemento HTML che inseriremo in pagina. Scegliamo ad esempio “user-details” e vediamo che, come conseguenza di quanto detto poco sopra, il nome della classe che rappresenta il Component diventa, in camel case, UserDetailsComponent.
31 - Spring Boot and Angular4 create a new Angular Component element name
Una volta deciso il nome del nostro Component, non ci resta che crearlo. Il comando della Angular Command-Line Interface da utilizzare per farlo è:

	ng g component <nome-elemento>


Ma noi stiamo utilizzando il wizard di creazione offerto da Spring Tool Suite e cliccando su “Next”, infatti, lo step successivo ci mostra proprio il comando Angular CLI che andrà ad eseguire per soddisfare la nostra richiesta di creazione del Component.
32 - Spring Boot and Angular4 ng g component
Cliccando su “Finish” il comando viene eseguito e il nuovo Component viene creato. La creazione di un nuovo Component comporta la creazione di:

  • Una nuova cartella con il nome dell’elemento creato quindi, nel nostro caso, “user-details”
  • Il file TypeScript del Component
  • Il template html con cui il nuovo Component sarà renderizzato
  • Il foglio di stile css con cui definire l’aspetto del template del Component

33 - Spring Boot and Angular4 create a new Angular Component created Inoltre, come possiamo vedere dai log dell’esecuzione del comando ng g component user-details, come ultimo step viene modificato il contenuto del modulo principale della nostra app Angular4.

Con

update src\app\app.module.ts

vengono infatti effettuate automaticamente le modifiche al Root Module dell’applicazione per includere il nuovo componente. Il suo codice, come possiamo vedere, diventa infatti il seguente:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { UserDetailsComponent } from './user-details/user-details.component';

@NgModule({
  declarations: [
    AppComponent,
    UserDetailsComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Binding del Component con gli oggetti della Classe

A questo punto dichiariamo nel nostro Component una variabile del tipo della nostra classe User, dopo averne importato il relativo riferimento. Decoriamo inoltre la variabile appena dichiarata con l’annotazione @Input() per indicare che il nostro Component riceverà dall’esterno l’oggetto con cui valorizzare tale variabile.
L’istruzione che aggiungiamo quindi è la seguente:

  @Input() user: User;

Il contenuto del file “user-details.component.ts”, che contiene la nostra classe UserDetailsComponent,diventa quindi quello illustrato di seguito:

import { Component, OnInit, Input } from '@angular/core';
import { User } from '../models/user';

@Component({
  selector: 'app-user-details',
  templateUrl: './user-details.component.html',
  styleUrls: ['./user-details.component.css']
})

export class UserDetailsComponent implements OnInit {

  @Input() user: User;

  constructor() { }

  ngOnInit() {
  }

}

34 - Spring Boot and Angular4 class and Component integration Input

Creare un array di oggetti della classe TypeScript

Dopo aver “agganciato” un’istanza della classe User del nostro model al componente UserDetailsComponent, siamo quasi pronti per visualizzare i nostri utenti in una tabella di una pagina web.

Prima però dobbiamo creare la lista degli utenti da mostrare. Per ora, li definiamo staticamente come array all’interno della nostra root application. Più avanti ce li faremo restituire da un controller REST del nostro progetto Spring Boot di back-end.

Andiamo quindi nella classe TypeScript della nostra root application “AppComponent”, e quindi nel file “app.component.ts” e creiamo un po’ di utenti utilizzando il costruttore che abbiamo definito.

  u1: User = new User('Davis', 'Molinari', 'Italy', 34);
  u2: User = new User('Lionel', 'Messi', 'Argentina', 30);
  u3: User = new User('Jason', 'Bourne', 'US', 30);

Una volta creati gli oggetti della classe User, li aggiungiamo ad un array.

  users: User[] = [this.u1, this.u2, this.u3];

35 - Spring Boot and Angular4 Root App Component defining objects

Definizione del Template del Component

Una volta creati gli oggetti della classe User e aver definito il Component, dobbiamo definire il relativo Template che indicherà come elementi di tale Component dovranno essere renderizzati su pagina web.

Supponiamo di voler visualizzare i dettagli dei nostri utenti in una tabella, di cui ogni User rappresenterà una riga. Definiremo quindi nella root application un ciclo for che per ogni elemento dell’array “user” genererà una riga di tipo UserDetailsComponent, il cui template conterrà le celle relative ai vari campi della classe User.

Editiamo quindi il template del nostro Component “UserDetailsComponent”, cioè il file “app.component.html”, in questo modo:

<td>{{user.firstname}}</td>
<td>{{user.lastname}}</td>
<td>{{user.country}}</td>
<td>{{user.age}}</td>

36 - Spring Boot and Angular4 User Component template

Scorrere l’array e renderizzare i template con Angular

Ora che abbiamo anche definito il template del nostro UserDetailsComponent non ci resta che modificare il template della root application in modo da definire la tabella che conterrà i relativi elementi che mostreranno i dati dei nostri utenti.

Per prima cosa modifichiamo il nostro HTML aggiungendo una tabella e definendo le colonne in cui saranno mostrate le informazioni sui nostri utenti. Nell’header della tabella inseriamo quindi le celle Firstname, Lastname, Country, Age:

<div style="text-align:center">
  <h1>
    Welcome to {{title}}!!
  </h1>
</div>
<div>
  <h1>
    List of Users
  </h1>
	<table>
		<thead>
			<tr>
				<th>Firstname</th>
				<th>Lastname</th>
				<th>Country</th>
				<th>Age</th>
			</tr>
		</thead>

Il body della tabella è la parte chiave della nostra pagina e rappresenta il posto in cui dobbiamo:

  • Ciclare sull’array “users” degli utenti che abbiamo definito nella root application
  • Inserire una riga che renderizzi il template del nostro Component
  • Passare, ad ogni iterazione, l’utente corrente al Component

Tutto questo lo riusciamo a fare con una singola riga di codice, la seguente:

		<tbody>
			<tr app-user-details *ngFor="let u of users" [user]="u"></tr>
		</tbody>

La prima cosa da notare è che in questo caso non stiamo renderizzando il nostro Component come elemento, cioè come tag HTML, vero e proprio ma come selettore, cioè come attributo di un elemento riga tr. Più avanti vedremo il perché di questa scelta.

*ngFor=”let u of users” è la direttiva da utilizzare per realizzare un ciclo for e ci permette di scorrere il nostro array “users” avendo un riferimento all’oggetto dell’iterazione corrente nella variabile “u”. La keyword let permette di definire una variabile locale al template che può essere referenziata ovunque al suo interno.

[user]=”u” è il meccanismo che ci permette di passare un parametro in input al nostro component. La sintassi prevede di mettere tra parentesi quadre il parametro per cui si vuole passare il valore e poi il valore stesso.

Nel nostro caso stiamo dicendo che vogliamo passare l’utente “u” dell’iterazione corrente come valore di Input per la proprietà “user” del nostro Component. Se andiamo a riprendere il nostro UserDetailsComponent, vediamo che avevamo definito la proprietà “user” come

  @Input() user: User;

37 - Spring Boot and Angular4 Root Application html template

Come ultimissima cosa dobbiamo fare una modifica al nostro componente “UserDetailsComponent” e quindi nel file “user-details.component.ts”.

La modifica consiste nello specificare che il Component deve poter essere usato siamo come elemento e quindi come tag “app-user-details” che come selettore di un altro elemento, come lo abbiamo utilizzato noi in precendenza con il tag “tr” per creare le righe “tr app-user-details …

Per fare questo dobbiamo modificare la linea:

selector: 'app-user-details',

in:

selector: 'app-user-details,[app-user-details]',

Indicando il nome del componente anche tra parentesi quadre, stiamo dicendo appunto che potrà essere utilizzato anche come selettore. Di default, invece, viene utilizzato come elemento.

Il codice completo del Component diventa quindi il seguente:

import { Component, OnInit, Input } from '@angular/core';
import { User } from '../models/user';

@Component({
  selector: 'app-user-details,[app-user-details]',
  templateUrl: './user-details.component.html',
  styleUrls: ['./user-details.component.css']
})

export class UserDetailsComponent implements OnInit {

  @Input() user: User;

  constructor() { }

  ngOnInit() {
  }

}

A questo punto proviamo ad eseguire la nostra applicazione.

Il risultato che otteniamo è illustrato nell’immagine seguente, dove possiamo vedere la tabella con le informazioni relative ai nostri utenti correttamente visualizzata.
39 - Spring Boot and Angular4 Application Running
Se apriamo i Developer Tools di Chrome possiamo vedere come all’interno delle righe della tabella che avevamo “etichettato” come app-user-details, sia stato sviluppato il Template del relativo Component e siano quindi state inserite le celle con i valori delle varie proprietà degli oggetti User.
40 - Spring Boot and Angular4 Application HTML code rendered table
Vai alla parte successiva dell’articolo: Creare una web application con Spring Boot, MongoDB, Angular 4 e TypeScript e deployarla in cloud come Microsoft Azure Webapp – Parte 5

This entry was posted in $1$s. Bookmark the permalink.

2 thoughts on “Creare una web application con Spring Boot, MongoDB, Angular 4 e TypeScript e deployarla in cloud come Microsoft Azure Webapp – Parte 4

  1. Pingback: Creare una web application con Spring Boot, MongoDB, Angular 4 e TypeScript e deployarla in cloud come Microsoft Azure Webapp – Parte 3 | Dede Blog

  2. Pingback: Creare una web application con Spring Boot, MongoDB, Angular 4 e TypeScript e deployarla in cloud come Microsoft Azure Webapp – Parte 5 | Dede Blog

Leave a Reply

Your email address will not be published. Required fields are marked *