Parte III — Il front-end JavaScript · Capitolo 8

SPA, framework JS e Angular

~45 min di lettura5 widget interattivi2 tavole

In questo capitolo

  1. Dai siti tradizionali alla Single Page Application
  2. Perché jQuery non basta
  3. La generazione dei framework JS
  4. Il confronto: criteri, requisiti, completezza
  5. Angular: definizione, linguaggi e CLI
  6. Moduli: gli NgModule
  7. Componenti e ciclo di vita
  8. Template e data binding
  9. Pipe e direttive
  10. Servizi e dependency injection
  11. Form, HTTP, routing e architettura dei dati
  12. Verifica le tue conoscenze

1. Dai siti tradizionali alla Single Page Application

Nei capitoli precedenti abbiamo costruito un back-end: un server Node.js con Express che serve dati REST e una base MongoDB che li conserva. Ora il punto di vista cambia e guardiamo il problema dall'altra parte: che cosa succede nel browser quando l'utente interagisce con l'applicazione. Il punto di partenza è il sito web tradizionale, che le slide chiamano server-based application: la pagina viene caricata completamente ogni volta che viene eseguita una richiesta al server.

I problemi di questo modello sono facili da elencare. Lato client: la pagina viene caricata completamente ad ogni richiesta; l'utente deve aspettare che tutti i file siano scaricati (HTML, CSS, JS, immagini); il contenuto scaricato deve essere renderizzato; non c'è business logic lato client; non c'è un modello MVC; senza rete l'applicazione non funziona. Lato server: ad ogni richiesta la pagina deve essere generata dall'inizio; si consuma banda per inviare sempre gli stessi file; tutte le computazioni sono eseguite lato server; un cambio di tecnologia implica la riscrittura completa del codice che gestisce il rendering della pagina.

Definizione

Single Page Application: «A Single Page Application is a web app in which the majority of interactions are handled on the client without the need to reach a server with a goal of providing a more fluid user experience». Le interazioni sono gestite prevalentemente lato client e il server viene raggiunto solo quando serve davvero.

I vantaggi dichiarati dalle slide sono sei: interazione app-like; i bottoni Indietro e Avanti del browser funzionano; possibilità di funzionamento anche offline; transizioni fluide tra i diversi stati delle pagine; CSS e JS inviati solamente nella richiesta iniziale; i cambiamenti alla pagina avvengono via JavaScript, usando template e la manipolazione del DOM.

2. Perché jQuery non basta

La tentazione è di risolvere tutto con la libreria che già conosciamo, jQuery: si manipola il DOM, si fanno chiamate AJAX, e l'applicazione "funziona". Ma le slide elencano quattro problemi strutturali. Lo stato dell'applicazione risiede nel DOM: i dati vivono negli attributi e nei nodi, non in una struttura dati esplicita. Di conseguenza lo stato guida il comportamento, e non il contrario: per sapere "in che stato siamo" bisogna interrogare la pagina. Si accoppia logica e presentazione: il codice che decide è mescolato al codice che mostra. E infine jQuery non è pensato per gestire la logica di un'applicazione: è una libreria di manipolazione del DOM, non un framework applicativo.

Attenzione

Il problema non è "jQuery è brutto": il problema è che l'applicazione non ha più un modello. Quando lo stato vive nel DOM, ogni vista è l'unica fonte di verità, e coordinare più viste sullo stesso dato diventa impossibile. I framework JS nascono esattamente da qui: servono a tenere lo stato fuori dal DOM e a far derivare il DOM dallo stato.

3. La generazione dei framework JS

Per le SPA nascono diverse tecnologie, librerie e framework. Un momento simbolico è la conferenza Throne of JS a Toronto (2012), dove gli sviluppatori dei maggiori framework JS si riuniscono per discutere come affrontare il bisogno delle nuove architetture SPA. Da quel momento la storia dei tre protagonisti è ben definita:

FrameworkStoria e longevità
AngularPrima release nel 2010 con il nome di AngularJS; la versione 2 è stata completamente riscritta ed è stata rilasciata nel 2016. Da lì in poi si chiama semplicemente Angular ed è un framework JavaScript lato client: se ne può utilizzare uno diverso. Release 1.0 nel 2012, subito molto popolare; al picco della popolarità (2014) il team annuncia una Angular 2 incompatibile con la precedente, in pratica una completa riscrittura. Settembre 2016: Angular 2; marzo 2017: versione 4; l'ultima versione citata è la 15 (febbraio 2023).
ReactRilasciato da Facebook nel marzo 2013 come open source, dopo essere stato usato in produzione per almeno due anni. Talvolta identificato come React.js/ReactJS; per la creazione di interfacce utente dedicate ad applicazioni web complesse, in modo semplice, veloce e scalabile.
Vue.jsRilasciato nel febbraio 2014 da Evan You, che aveva lavorato nel team di sviluppo di AngularJS. Nasce come alternativa "leggera" ad Angular: una curva di apprendimento bassa ma la capacità di crescere fino ad applicazioni molto complesse.

La storia conta, ma da sola non basta: le slide la inseriscono tra i sei criteri del confronto, e gli altri cinque sono popolarità ed ecosistema, supporto aziendale, esperienza iniziale e curva di apprendimento, capacità richieste, completezza e performance. Il messaggio della lezione è una sola parola: dipende.

4. Il confronto: criteri, requisiti, completezza

Il supporto aziendale si riassume in una riga: Angular è sponsorizzato da Google, React da Facebook, mentre Vue.js riceve supporto da svariate organizzazioni di piccola/media dimensione, principalmente attraverso Patreon, un tool online dedicato ai creatori di servizi.

L'esperienza iniziale è molto diversa. Angular richiede di installare la CLI e impostare alcuni parametri prima di scrivere codice; React offre due guide, una con lo snippet dell'"Hello World" e una step-by-step completabile in un'ora; Vue basta includerlo con un tag <script>. La curva di apprendimento migliore è quella di Vue, seguito da React, che richiede un tempo leggermente superiore; Angular è distanziato, perché il suo scopo è consentire la realizzazione di applicazioni di nuova generazione anche a livelli di complessità elevati.

// installazione CLI
npm install -g @angular/cli
// creazione di un nuovo progetto
ng new my-app
// avvio del server ('open' apre automaticamente il browser)
cd my-app ng serve --open

L'esperienza iniziale di Angular è la più complessa. A questo punto si lavora sui file dei componenti generati, come src/app/app.component.ts, e per iniziare occorre seguire il tutorial Tour of Heroes.

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('root')
);

React assume che lo sviluppatore sappia scrivere JavaScript conforme agli ultimi standard ECMA (6): le keyword let e const, la keyword class, le arrow functions =>. Fa uso di JSX, un'estensione della sintassi JavaScript utile a mescolare HTML e JS in un unico codice — non obbligatoria, ma quasi impossibile da evitare nelle applicazioni reali.

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
  <button @click="count++">Count is {{ count }}<button>
</div>

Vue è un framework progressivo: alcune componenti non sono incluse di default, ma esistono librerie ufficiali che aggiungono le varie funzionalità, con un'ottima documentazione. La CLI vue-cli è sconsigliata a chi usa Vue.js per la prima volta o ha scarsa dimestichezza con Node.js.

I requisiti richiesti da ciascun framework spiegano molto della curva di apprendimento:

FrameworkRequisiti
ReactJS (ES6+), JSX, CSS-in-JS
Vue.jsHTML, JS (ES5+), CSS
AngularTypeScript

La voce "capacità richieste" riguarda soprattutto Angular: è stato scritto in TypeScript, quindi occorre conoscerlo per lavorarci. Uno sviluppatore JavaScript "standard" avrà maggiori difficoltà, dovendo prendere confidenza con la tipizzazione statica; un programmatore che proviene da C# o Java, linguaggi a tipizzazione statica, si troverà maggiormente a suo agio.

La completezza li divide in tre livelli. Angular è il framework nativamente più completo: la sua struttura all-in-one fornisce UI management, state management, routing, test end-to-end e molto altro. React è improntato principalmente sulla UI: per funzionalità avanzate serve estendere il core con strumenti esterni, come Redux e MobX per la gestione dello stato. Vue.js è un framework progressivo: il core è principalmente basato sul livello delle View, e per le funzionalità aggiuntive servono componenti extra, sia di terze parti sia ufficiali, come Vuex per lo state management centralizzato. Il riassunto delle slide è un criterio di scelta pratico: una soluzione full-featured come Angular potrebbe non essere la scelta migliore per un'applicazione che non necessita di tutte le sue funzionalità o che va realizzata in tempi brevi.

Sul piano delle performance: a causa della sua completezza all-in-one, Angular risulta la libreria più pesante, segue React e infine Vue. I benchmark mostrano una leggera deviazione di performance tra i tre, con Angular il più "lento" e Vue il più "veloce".

Perché il corso sceglie Vue

Le slide chiudono il confronto con una sintesi che è anche il programma del corso: Vue si può apprendere rapidamente, è vicino alla versione "classica" di HTML/CSS/JavaScript, si può espandere progressivamente con la complessità dell'applicazione ed è veloce e leggero. Per questo il corso lo studia in dettaglio, mentre di Angular dà un'introduzione — ed è proprio l'ordine che seguiamo nei prossimi due capitoli.

5. Angular: definizione, linguaggi e CLI

Angular è un framework open-source per lo sviluppo di Single Page Application. È una completa riscrittura, in TypeScript, di AngularJS, da parte dello stesso team di sviluppo; è un progetto manutenuto principalmente da Google e fa parte dello stack MEAN (MongoDB, Express, Angular, NodeJS).

È possibile sviluppare applicazioni in TypeScript, Dart o JavaScript: sebbene venga lasciata libertà di scelta, è consigliabile l'utilizzo di TypeScript. A disposizione c'è una Command Line Interface che semplifica la creazione della struttura dell'applicazione, basata su Node e installabile con npm install -g angular-cli. I comandi principali sono tre:

ComandoFunzione
ng new appnamecreazione di un nuovo progetto
ng serve --openserve l'applicazione (è necessario entrare prima nella cartella del progetto: cd appname)
ng build --prod --bh /myUrl/esegue il build dell'applicazione, indicando il base href

6. Moduli: gli NgModule

Angular ha un proprio sistema di moduli, chiamato Angular modules o NgModules. Ogni applicazione ha almeno un modulo Angular — il modulo root, solitamente chiamato AppModule. Un NgModule è una classe con un decoratore @NgModule, che prende in input un oggetto metadata le cui proprietà descrivono il modulo:

ProprietàRuolo
declarationsspecifica le view classes (components, directives e pipes) appartenenti al modulo
exportssottoinsieme delle view classes di declarations che dovrebbero essere visibili e utilizzabili nei componenti di altri moduli
importsspecifica le classi esportate da altri moduli necessarie alle classi dichiarate in questo modulo
providerscreatori di servizi che questo modulo aggiunge alla collezione globale di servizi, accessibili in tutte le parti dell'applicazione
bootstrapindica l'application view principale, che ospita tutte le altre: solo il modulo root dovrebbe settare questa proprietà
Per l'esame

La domanda classica è "quali sono le proprietà principali di @NgModule?". Cinque, e conviene ricordarle con il loro ruolo: declarations (cosa appartiene a questo modulo), exports (cosa mostro agli altri), imports (cosa prendo dagli altri), providers (quali servizi rendo globali), bootstrap (quale vista avvia l'applicazione — solo nel root).

7. Componenti e ciclo di vita

I Component sono le unità di base delle UI delle applicazioni Angular: un'applicazione è un albero di componenti. Un Component è una classe "adornata" con il decoratore @Component: questa classe rende disponibili dei dati al template e gestisce la logica di interazione con l'utente. Le proprietà principali del decoratore sono selector (il selettore CSS che identifica il componente in un template), template/templateUrl (la vista, inline o in un file esterno) e styles/styleUrls (lo stile, inline o esterno).

Nota del redattore

Le slide sollevano una domanda: cosa succede se specifico sia styles che styleUrls? La risposta è che non esiste una priorità sulle regole: viene semplicemente utilizzato lo stile specificato nell'ultima proprietà definita. Un dettaglio che sembra banale, ma che nei colloqui tecnici è usato proprio per capire se qualcuno ha letto la documentazione.

Il modo in cui si progetta un albero di componenti è illustrato con il mockup di una Inventory Management App: dato il disegno della pagina, si suddividono gli elementi in componenti di alto livello — Navigation Component, Breadcrumbs Component e Product List Component — e poi si scende di livello: Product List può essere diviso in Product Row, e ogni Product Row in Product Image, Product Department e Price Display.

I lifecycle hook

I metodi "hook" sono eventi a cui è possibile registrarsi e che vengono chiamati da Angular durante il ciclo di vita di direttive e componenti. Questi metodi di callback sono chiamati dopo la chiamata al costruttore, nell'ordine riportato dalle slide. Esplorateli con il widget: ogni hook descrive il momento in cui Angular lo invoca.

Memory leak

ngOnDestroy è il posto giusto dove fare gli unsubscribe degli Observable, per evitare memory leak: se un componente muore ma resta iscritto a uno stream, la callback continuerà a vivere (e a consumare) per sempre.

8. Template e data binding

Il template rappresenta la vista del componente, ovvero come deve essere renderizzato; è composto da tag HTML e dalla sintassi di Angular per il template. Il data binding è il meccanismo per coordinare la comunicazione tra un componente e il suo template: aggiungendo al template HTML il markup per eseguire il binding, si specifica ad Angular come connettere il DOM e il Component. Le direzioni possibili sono quattro, ed è importante distinguerle:

La interpolazione usa le doppie parentesi graffe: l'espressione viene valutata e infine convertita in una stringa. Sono proibite espressioni che hanno side effect (come gli assegnamenti), e le espressioni possono contenere proprietà del Component che controlla la vista. Il property binding usa le parentesi quadre: l'espressione tra i doppi apici viene valutata e assegnata all'attributo di un elemento del DOM, con le stesse considerazioni dell'interpolazione.

<p>
  <img src="{{heroImageUrl}}"> is the
  <i>interpolated</i> image.
</p>
<p>
  "<span>{{title}}</span>" is the
  <i>interpolated</i> title.
</p>

L'espressione dentro le parentesi graffe viene valutata e convertita in stringa. Per leggibilità, è la forma che si tende a preferire.

<p>
  <img [src]="heroImageUrl"> is the
  <i>property bound</i> image.
</p>
<p>
  "<span [innerHTML]="title"></span>"
  is the <i>property bound</i> title.
</p>

Il property binding assegna il valore all'attributo del DOM: [innerHTML] è il corrispettivo di interpolare il titolo dentro uno span.

Angular traduce le interpolazioni nella corrispondente property binding prima di renderizzare la vista: non ci sono motivi tecnici per preferire una forma all'altra, e considerando la leggibilità si tende a preferire l'interpolazione.

L'event binding consente di definire un handler per un determinato evento, ad esempio i movimenti del mouse o i click: <button (click)="onSave()">Save</button>. Il two-way data binding è l'unione di property ed event binding: il valore fluisce dal DOM al component e viceversa, con la sintassi "banana in a box" — <input [(ngModel)]="element" /> — che è l'abbreviazione di [ngModel] più (ngModelChange)="element = $event". Il data binding è importante anche per la comunicazione tra component padre e figlio.

Idea chiave

Le tre sintassi si riconoscono a colpo d'occhio: {{ }} porta il componente nel template (interpolazione), [ ] lega una proprietà del DOM a un'espressione, ( ) ascolta un evento dal template. Le parentesi quadre e tonde insieme, [( )], sono le due direzioni unite.

9. Pipe e direttive

Le Pipe sono un modo di scrivere trasformazioni di un valore direttamente nel template: {{ value | pipe }}. È possibile parametrizzarle — Today is {{ curdate | date:"dd/MM/yy" }} — e concatenarle. Le pipe built-in includono DatePipe, UpperCasePipe, CurrencyPipe e PercentPipe; pipe personalizzate si creano con il decoratore @Pipe.

Le direttive sono di tre tipi: i Components, che sono direttive con un template; le direttive strutturali, che cambiano il layout del DOM aggiungendo o rimuovendo elementi; le direttive dell'attributo, che cambiano l'aspetto o il comportamento di un elemento, componente o di un'altra direttiva.

Direttive strutturali

Si applicano a un elemento "host", con cui la direttiva fa tutto quello che deve fare (anche con i suoi discendenti), e sono semplici da riconoscere: il loro nome è preceduto da un asterisco. Le built-in sono ngIf, ngSwitch e ngFor.

Direttive dell'attributo

Idealmente, una direttiva dovrebbe lavorare in modo da essere "component agnostic" e non legata ai dettagli implementativi. Le built-in sono ngClass, ngNonBindable e ngStyle:

Infine <ng-container> è un elemento di raggruppamento che non interferisce con lo stile o con il layout, perché Angular non lo aggiunge al DOM: si usa quando non si ha a disposizione un elemento "contenitore" o quando si vuole applicare una direttiva a semplice testo.

10. Servizi e dependency injection

I servizi sono una vasta categoria che comprende qualsiasi valore, funzione o caratteristica di cui l'applicazione ha bisogno; un servizio è tipicamente una classe con uno scopo ben definito, come il logging o il caricamento di dati. Angular non ha una definizione formale di servizio: non prevede una classe base né un posto obbligatorio in cui registrarli.

La divisione dei compiti è netta: il compito del Component è di gestire la User eXperience. Un Component non dovrebbe caricare i dati dal server o validare l'input di un utente: questi compiti devono essere delegati ai servizi.

La dependency injection è un modo di fornire una nuova istanza di una classe con le dipendenze che richiede pienamente formate. Molte dipendenze sono servizi, e Angular stabilisce di quali servizi un component necessita guardando i tipi dei parametri del costruttore. Quando crea un componente, Angular chiede all'injector i servizi richiesti; l'injector mantiene un container delle istanze dei servizi già creati e, se l'istanza richiesta non c'è, la crea e la aggiunge al container; quando tutti i servizi sono risolti, chiama il costruttore con quelli come argomenti.

Injection gerarchica

Il sistema di dependency injection è gerarchico e segue la gerarchia dei componenti: ogni componente ha a disposizione un "injector" a cui chiedere se esiste un'istanza del servizio o un provider per istanziarla; se non esiste, l'injector chiede la dipendenza all'injector del componente padre, risalendo la gerarchia. Un servizio si può dichiarare a livello di bootstrap (tutti i componenti avranno la stessa istanza) oppure a livello di componente (l'istanza è condivisa solo dal componente in cui è dichiarato il provider e dai suoi figli).

11. Form, HTTP, routing e architettura dei dati

Angular mette a disposizione strumenti completi per la gestione dei form: FormControl incapsula in un oggetto l'input del form e il suo stato (valido, sporco, con errori); FormGroup è un wrapper di una collezione di FormControl; i Validator validano l'input; gli Observer rilevano cambiamenti e reagiscono di conseguenza.

Per le chiamate API esterne c'è una libreria HTTP propria, asincrona, con i metodi get, post, put e così via. I tre approcci principali alla programmazione asincrona sono Callbacks, Promises e Observables: l'approccio scelto da Angular sono gli Observables — i metodi di HTTP restituiscono degli Observables, e Angular incorpora RxJS e lo usa internamente.

Per la navigazione tra più pagine c'è il modulo Router. Servono quattro passaggi: inserire il tag html <base> nella pagina principale; definire le rotte come array di oggetti che mappano i path ai component; inserire la direttiva router-outlet nella view principale; definire dei link con l'attributo routerLink.

Sulla data architecture Angular è estremamente flessibile: ci sono molti modi per ottenere dati — richieste AJAX, Websockets, local storage, Service Workers — e Angular non consiglia un'architettura particolare ma cerca di rendere facile l'uso di quella scelta. Le architetture più utilizzate sono MVC/two-way data binding, Flux (pattern basato su un flusso di dati unidirezionale) e Observables (ci si iscrive a stream di dati e si eseguono azioni in reazione ai cambiamenti).

Due note di integrazione. Nonostante le differenze tra AngularJS e le versioni successive esistono costrutti per l'interoperabilità: è possibile creare applicazioni ibride che eseguono contemporaneamente AngularJS e Angular, molto utile per aggiornare incrementalmente le applicazioni basate su AngularJS. E NativeScript è un framework per lo sviluppo cross platform di applicazioni mobile basato su JavaScript, TypeScript o Angular: come React Native e Xamarin, non renderizza una web view ma utilizza i componenti UI nativi, migliorando le performance. Chiude il quadro la Style Guide della documentazione ufficiale, che regola sintassi, convenzioni e struttura dell'applicazione con raccomandazioni divise in Do (dovrebbe essere sempre seguita), Consider (dovrebbe generalmente essere seguita), Avoid (non dovrebbe mai essere fatto) e Why? (il motivo della raccomandazione).

Verifica le tue conoscenze

Quali sono i problemi del modello server-based, lato client e lato server?

Lato client: la pagina viene caricata completamente a ogni richiesta; l'utente attende il download di tutti i file (HTML, CSS, JS, immagini); il contenuto scaricato deve essere renderizzato; non c'è business logic client side né modello MVC; senza rete l'applicazione non funziona. Lato server: ad ogni richiesta la pagina viene generata dall'inizio; si consuma banda per inviare sempre gli stessi file; tutte le computazioni sono lato server; un cambio di tecnologia implica la riscrittura completa del codice che gestisce il rendering.

Definite la Single Page Application e i suoi vantaggi.

«A Single Page Application is a web app in which the majority of interactions are handled on the client without the need to reach a server with a goal of providing a more fluid user experience». Vantaggi: interazione app-like; bottoni Indietro/Avanti funzionanti; possibilità di funzionamento offline; transizioni fluide tra gli stati; CSS e JS inviati solo nella richiesta iniziale; cambiamenti alla pagina via JavaScript, con template e manipolazione del DOM.

Perché jQuery non è adatto a gestire la logica di un'applicazione?

Per quattro motivi: lo stato dell'applicazione risiede nel DOM; di conseguenza lo stato guida il comportamento (per sapere in che stato siamo bisogna interrogare la pagina); si accoppia logica e presentazione; jQuery non è pensato per gestire la logica di un'applicazione, essendo una libreria di manipolazione del DOM.

Riepilogo della storia dei tre framework: Angular, React, Vue.

AngularJS: release 1.0 nel 2012, molto popolare; nel 2014 il team annuncia Angular 2, incompatibile e in pratica una completa riscrittura; settembre 2016: Angular 2; marzo 2017: versione 4; ultima citata la 15 (febbraio 2023). React: rilasciato da Facebook nel marzo 2013 (open source) dopo due anni di uso in produzione. Vue.js: rilasciato nel febbraio 2014 da Evan You, ex membro del team di AngularJS, come alternativa leggera ad Angular.

Confrontate i tre framework su requisiti, completezza e performance.

Requisiti: React richiede JS (ES6+), JSX e CSS-in-JS; Vue.js HTML, JS (ES5+) e CSS; Angular TypeScript. Completezza: Angular è all-in-one (UI, state, routing, test e2e); React è improntato sulla UI, con strumenti esterni come Redux e MobX per lo stato; Vue è progressivo, con core basato sulle View e componenti aggiuntivi ufficiali come Vuex. Performance: Angular è la più pesante e la più "lenta" nei benchmark, segue React, e Vue è la più veloce e leggera, con una deviazione comunque leggera.

Che cos'è un NgModule e quali sono le proprietà principali di @NgModule?

È il sistema di moduli di Angular: ogni applicazione ha almeno il modulo root (AppModule), una classe con il decoratore @NgModule e un oggetto metadata. Proprietà: declarations (view classes del modulo), exports (sottoinsieme visibile ad altri moduli), imports (classi esportate da altri moduli), providers (servizi aggiunti alla collezione globale), bootstrap (application view principale, solo nel modulo root).

Descrivete le quattro direzioni del data binding in Angular.

Interpolazione {{...}}: l'espressione è valutata e convertita in stringa nel template. Property binding [src]: l'espressione è valutata e assegnata a un attributo del DOM. Event binding (click): definisce un handler per un evento del template. Two-way [(ngModel)]: unione di property ed event binding, "banana in a box", il valore fluisce dal DOM al component e viceversa. Angular traduce le interpolazioni in property binding prima di renderizzare; per leggibilità si preferisce l'interpolazione.

Quali sono le direttive strutturali built-in di Angular e come si riconoscono?

Sono ngIf (mostra o rimuove un elemento in base a una condizione falsy/truthy), ngSwitch (con ngSwitchCase e ngSwitchDefault) e ngFor (ripete un elemento su una collezione, con i valori esportati index, first, last, even, odd). Si riconoscono perché il loro nome è preceduto da un asterisco e si applicano a un elemento host.

Che rapporto c'è tra Component e Service, e come funziona la dependency injection?

Il Component gestisce la User eXperience e non dovrebbe caricare dati dal server né validare input: questi compiti vanno delegati ai servizi, classi con uno scopo ben definito. La dependency injection fornisce a una classe le dipendenze richieste già formate: Angular guarda i tipi dei parametri del costruttore, chiede i servizi all'injector, che mantiene un container di istanze (creandone una se manca), e poi chiama il costruttore. Il sistema è gerarchico: l'injector di un componente risale verso i padri se non trova il servizio.

Quali strumenti Angular offre per form, HTTP e routing?

Form: FormControl (input + stato valido/sporco/errori), FormGroup (collezione di FormControl), Validator, Observer. HTTP: libreria propria asincrona con get/post/put; tra Callbacks, Promises e Observables, Angular sceglie gli Observables e incorpora RxJS. Routing: tag <base> nella pagina principale, rotte come array che mappano i path ai component, direttiva router-outlet nella view principale, link con routerLink.