Vai al contenuto

Il framework AngularJs in dettaglio

Nell’articolo precedente abbiamo dato una prima occhiata al framework AngularJs e alle sue potenzialità. Quello che abbiamo visto non è altro che la punta dell’iceberg: man mano andremo sempre più a fondo per scoprire le caratteristiche salienti.

Nel mondo reale un’applicazione è composta oltre che da codice HTML, seppur arricchito, anche da codice JavaScript. Quando si ha a che fare con Angular, bisogna seguire un percorso strutturato e modulare composto da componenti che hanno ciascuno una precisa funzione. Tali componenti sono i seguenti:

Componente Descrizione
View Rappresenta l’interfaccia grafica generata a partire da un template HTML elaborato da Angular.
Direttiva È un componente che estende l’HTML con tag ed attributi personalizzati; è l’unico componente autorizzato a manipolare il DOM via JavaScript
Controller È un oggetto JavaScript che espone dati e funzionalità ad una view.
Filtro È una funzione che formatta il valore di un’espressione per la visualizzazione su una view (es formattazione di una data o di un numero o la selezione di un sottoinsieme di elementi di un array).
Servizio È un oggetto che fornisce funzionalità indipendenti dall’interfaccia grafica, come ad esempio l’accesso al server via HTTP.

Le View

Una view non è altro che una pagina HTML con arricchimenti di nuove direttive (ng-app, ng-init e cosi via) con le quali possiamo applicare specifici comportamenti ai TAG HTML. Quando Angular avvia l’applicazione, analizza ed elabora le direttive dal modello utilizzando il proprio compilatore, che trasforma il modello DOM contenuto all’interno della pagina nella view. Di seguito un ipotetico esempio di view:

<div ng-app ng-init="qty=1;cost=2">
  <b>Fattura:</b>
  <div>
    Quantità: <input type="number" min="0" ng-model="qty">
  </div>
  <div>
    Costo: <input type="number" min="0" ng-model="cost">
  </div>
  <div>
    <b>Totale:</b> {{qty * cost | currency}}
  </div>
</div>

Le Direttive (directive)

Le direttive di AngularJS sono dei marcatori che estendono il linguaggio HTML o che modificano il comportamento di un elemento HTML standard. Questi elementi dell’architettura di Angular sono gli unici componenti “autorizzati” alla manipolazione del DOM e quindi ad intervenire sull’interfaccia utente. Ne abbiamo già visto qualcuno: ng-app, ng-controller, ng-init, ng.model.

Il compilatore di AngularJs effettua una normalizzazione dei tag per identificare cosa fa parte dei tag HTML e cosa invece fa parte delle direttive di Angular. La regola che viene seguita è questa:

  1. Cancella il prefisso x- e data- dagli attributi del tag.
  2. Cancella i simboli :, -, o _ e trasforma l’attributo secondo lo stle camelCase.

Per questo motivo, le direttive possono anche essere scritte in modi alternativi, tutti validi:

<div ng-controller="Controller">
	Hello <input ng-model='name'> <hr/>
	<span ng-bind="name"></span> <br/>
	<span ng:bind="name"></span> <br/>
	<span ng_bind="name"></span> <br/>
	<span data-ng-bind="name"></span> <br/>
	<span x-ng-bind="name"></span> <br/>
</div>

Riepilogo delle direttive principali:

ng-app Inizializza un’applicazione AngularJS
ng-init Definisce i valori iniziali per un’applicazione AngularJS
ng-model Associa il valore di controlli HTML (input, selection, textarea) con i dati dell’applicazione
ng-bind Sostituisce il contenuto di un elemento HTML con il risultato della valutazione di un’espressione e aggiorna tale contenuto quando il valore dell’espressione cambia. Equivalente alle espressioni Angular racchiuse tra parentesi graffe. Le seguenti espressioni sono equivalenti:

<span ng-bind="2 + 3"></span>
<span>{{ 2+ 3 }}</span>
ng-show e ng-hide Consentono di visualizzare o meno elementi sulla pagina in base alla valutazione di una espressione, basata su condizioni booleane.
ng-if Controllo condizionale. Visualizza porzioni dell’interfaccia utente in base ad una condizione booleana

<div ng-controller="studenteController">
    <p>Nome:    <input type="text" ng-model="studente.nome"></p>
    <p>Cognome: <input type="text" ng-model="studente.cognome"></p>
    <p ng-if="studente.nome || studente.cognome">{{studente.saluta()}}</p>
</div>
ng-switch Classico controllo presente in molti linguaggi di programmazione. Consente di visualizzare una porzione di interfaccia in base al confronto tra una espressione di controllo ed un elenco di possibili valori

<p>Colore: <input type="text" ng-model="colore"></p>
 
<div ng-switch="colore">
    <span ng-switch-when="rosso" style="color:red">{{colore}}</span>
    <span ng-switch-when="verde" style="color:green">{{colore}}</span>
    <span ng-switch-when="blu"   style="color:blue">{{colore}}</span>
    <span ng-switch-default      style="color:black">{{colore}}</span>
</div>
ng-include Consente di includere, nella view corrente, codice HTML esterno proveniente cioè in un altro file

<div ng-include="'dati/documento.html'"></div>
ng-class Permette di impostare dinamicamente classi CSS ad un elemento HTML

<style type="text/css">
  .rosso {color: red}
  .verde {color: green}
  .blu {color: blue}
</style>
<p>Colore: <input type="text" ng-model="colore"></p>
<p ng-class="colore">È stato scelto il colore {{colore}}</p>
ng-repeat  ripete un elemento HTML

<div ng-app="" ng-init="names=['Jani','Hege','Kai']">
  <ul>
    <li ng-repeat="x in names">
      {{ x }}
    </li>
  </ul>
</div>

Direttive di evento

Sono direttive di evento per gestire gli eventi di interazione dell’utente con l’interfaccia grafica.  Le direttive di evento assomigliano ai classici gestori di evento JavaScript quali onclick, ondblclick, ecc.

  • ng-click
  • ng-dbl-click
  • ng-mousedown
  • ng-mouseup
  • ng-mouseenter
  • ng-mouseleave
  • ng-mousemove
  • ng-mouseover
  • ng-keydown
  • ng-keyup
  • ng-keypress
  • ng-change

Esempio classico:

<div>
	<input type="number" ng-model="a"/> +
	<input type="number" ng-model="b"/> =
	<input type="number" ng-model="ris"/>
</div>
<button onclick="ris = a + b">Somma</button>

I Controller

AngularJS si basa principalmente su controller per controllare il flusso dei dati nell’applicazione. Un controller è un classico oggetto JavaScript contenente attributi / proprietà e funzioni. All’interno del controllore è possibile usare il parametro $scope, uno speciale oggetto che viene passato dal framework al controller ed è condiviso con la view. In questo modo, lo $scope funge da legame tra la view e il controller. L’associazione tra una view e un controller avviene sull’HTML tramite la direttiva ng-controller. Ecco la view:

<div ng-app="mainApp" ng-controller="studenteController">
	Cognome: <input type="text" ng-model="studente.cognome"><br><br>
	Nome: <input type="text" ng-model="studente.nome"><br>
	<br>
		 
	Studente selezionato: {{studente.nomeCompleto()}}
</div>

Ed ecco la definizione del controller:

<script>
	var app = angular.module("mainApp", []);
	app.controller('studenteController', function($scope) {
		$scope.studente = {
		   cognome: "Mario",
		   nome: "Rossi",
		   nomeCompleto: function() {
			  var studenteObj;
			  studenteObj = $scope.studente;
			  return studenteObj.nome + " " + studenteObj.cognome;
		   }
		};
	});
</script>

La prima riga crea un modulo chiamato “app” (con riferimento a ng-app=”mainApp”) che conterrà le istruzioni della nostra applicazione. Dalla seconda riga in poi, viene creato il controller: in particolare all’interno di un oggetto studente (in $scope) vengono definiti due attributi (nome e cognome) e una funzione nomeCompleto che restituisce i valori dei due attributi concatenati. Nella view per richiamarli (vedi sopra) basta utilizzare ng-model=”studente.cognome” oppure {{studente.nomeCompleto() }}

Il data binding di AngularJs è bidirezionale (two-way binding), cioè ogni modifica al modello dei dati si riflette automaticamente sulla view e ogni modifica alla view viene riportata sul modello dei dati, a differenza della maggior parte dei sistemi di template che invece supporta il data binding unidirezionale, tipicamente dal modello dei dati verso la view.

I Filtri

I filtri vengono utilizzati per formattare o modificare i dati all’interno della view. Il loro utilizzo avviene mediante l’uso del carattere pipe (|). Segue l’elenco dei filtri più usati:

Nome Descrizione
uppercase converte il testo in maiuscolo
lowercase converte il testo in minuscolo
currency formatta il testo in formato valuta
filter Filtra gli elementi di un array che soddisfano un determinato criterio
orderby Ordina gli elementi di un array in base a un determinato criterio
number formatta un numero
date formatta una data

I filtri vanno applicati alle espressioni delle view utilizzando la seguente sintassi:

{{ expression | filter }}

Ad esempio, con {{ 12 | currency }}  il numero 12 viene formattato come valuta, cioè: €12,00

I filtri possono essere applicati al risultato di un altro filtro. La tecnica si chiama “chaining” e utilizza la seguente sintassi:

{{ expression | filter1 | filter2 | ... }}

I filtri possono inoltre avere argomenti. La sintassi è

{{ expression | filter:argument1:argument2:... }}

Ad esempio, {{ 1234 | number:2 }} darà come output 1.234,00

I Servizi

Un servizio è una funzione o un oggetto, che è disponibile per, e limitata a, l’applicazione AngularJS che offrono funzionalità indipendenti dall’interfaccia utente. AngularJS ha circa 30 servizi incorporati. Vediamone alcuni di seguito.

$location

Questo servizio contiene metodi che restituiscono informazioni sulla posizione della pagina Web corrente. Maggiori informazioni si possono trovare nella guida ufficiale, qui

var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $location) {
    $scope.myUrl = $location.absUrl();
});

$http

E’ uno dei servizi più usati nelle applicazioni AngularJS. Il servizio permette di fare richieste al server e nel contempo gestire la risposta proveniente dal server. Maggiori informazioni si possono trovare nella guida ufficiale, qui.

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
    $http.get("welcome.htm").then(function (response) {
        $scope.myWelcome = response.data;
    });
});

$timeout

E’ la versione AngularJS della funzione Javascript window.setTimeout. Maggiori informazioni si possono trovare nella guida ufficiale, qui.

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $timeout) {
    $scope.myHeader = "Hello World!";
    $timeout(function () {
        $scope.myHeader = "How are you today?";
    }, 2000);
});

$interval

E’ la versione AngularJS della funzione window.setInterval. Maggiori informazioni si possono trovare nella guida ufficiale, qui.

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $interval) {
    $scope.theTime = new Date().toLocaleTimeString();
    $interval(function () {
        $scope.theTime = new Date().toLocaleTimeString();
    }, 1000);
});

Servizi personalizzati

Per creare un servizio personalizzato basta collegare al modulo app, il nuovo servizio in questo modo:

var app = angular.module('myApp', []);
app.service('hexafy', function() {
    this.myFunc = function (x) {
        return x.toString(16);
    }
});