Sviluppare Web Apps con            

claudio.bisconti@commitsoftware.it

è un framework javascript

(Non chiamatelo libreria)

 

che si propone di risolvere

(o almeno semplificare)

lo sviluppo e la manutenzione

delle applicazioni web

  • è Open Source (GitHub, MIT)
  • lo mantiene Google
  • Utilizza dei design pattern come MVC / MVVM
  • Ha un compilatore di HTML
  • Ti aiuta a scrivere meno codice rispetto ad altri framework
  • Ha moltissimi "add-on"
  • Ha moltissimi sviluppatori nella comunità
  • Ha delle suite per fare "test"
  • E puoi anche usarlo per creare applicazioni mobile
  • ...

Perchè

?

Struttura: MVC

View

Model

Controller

Notifies

Notifies

Changes

HTML

Classi Javascript

Oggetti Javascript

Two-way Data Binding

From One-way to...

Two-way Data Binding

<input id="name3" value="Pippo">
<p>Ciao <span id="greeting3"></span>!</p>
 
<script>
$(function() {
  var name = $('#name3');
  var greeting = $('#greeting3');
 
  function update() {
    greeting.text(name.val());
  }
  update();
 
  name.bind('keydown', function() {
    setTimeout(update, 0);
  });
});
</script>

<input name="name3" value="Pippo">
<p>Ciao {{ name3 }}!</p>

Two-way Data Binding

Iniziamo!

<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js">
  </script>
</head>

<body ng-app="DemoApp">
  <div class="user-container" ng-controller='UserController'>
    <input name="name" ng-model="user.name">
    <p>Ciao {{ user.name }}!</p>
  </div>

<script>
  angular.module('DemoApp', [])
  .controller('UserController', function($scope) {
      $scope.user = {
        name : 'Pippo',
        age : '99'
      };
  });
</script>
</body>
</html>

ng-app

Questa direttiva viene usata per far partire angular in automatico

 

Ogni elemento HTML al di fuori di ng-app non viene gestito da Angular

<html>
  ...
  <body>
    <!-- Non gestito da Angular -->

    <div ng-app="DemoApp">
        <!-- Gestito da Angular -->
    </div>

    <!-- Non gestito da Angular, ex: footer -->
  </body>
</html>

HTML Compiler

Il compilatore interno di Angular ci permette di aggiungere all'HTML della nuova sintassi

<div>
<a>
<span>
<section>
<article>
<body>
...
<rating>
<tabs>
...
<!--
possiamo anche crearne
dei nostri
-->
<what-you-want>
<ciaone>
...

Standard

Custom

Directives

Le direttive sono "funzioni" per estendere l'HTML

  • ng-app = "NomeApp"
    Identifica dove viene creata l'applicazione Angular
     
  • ng-controller = "NomeController"
    Identifica ed associa a tutta la parte dell'HTML un Controller ben preciso
     
  • ng-model = "Modello"
    Inizializza il Two-Way Data Binding a partire dal modello specificato

Directives

  • ng-if = "model"
    Sceglie se creare o meno l'elemento HTML in base al modello specificato, se è "vero" allora crea l'HTML
     
  • ng-show = "model"
  • ng-hide = "model"
    Visualizza o meno l'HTML in questione se il modello è "vero"
     
  • ng-repeat = "element in model"
    Esegue N volte la creazione dell'HTML in base al numero di elementi contenuti sul modello

Directives

  • ng-click = "funzione(...)"
    Esegue "funzione" al click sull'elemento
     
  • ng-class = "model"
    Inserisce nuove classi CSS all'elemento HTML in base al modello
     
  • ng-change = "funzione(...)"
    Utilizzato nei form, alla variazione dell'input, esegue "funzione"

Directive as components

Puoi utilizzare alcune direttive al posto dei tag HTML


 <rating max='5' model='stars.average'>

 <tabs>
   <tab title='Static title' view='...'>
   <tab title='{{ tab.title }}' view='...'>
 </tabs>

 <tooltip content='messages.hello'>

Expressions

Angular consente di scrivere espressioni utilizzando la sintassi Javascript

 

Angular "osserva" le espressioni in base al cambiamento dei suoi elementi


 <input type="number" ng-model="money" />

 <input type="number" ng-model="iva" />

 <div class="result">
   {{ (money + (money * iva / 100)) }}
 </div>

Filters

I filtri sono componenti che permettono di modificare il testo in tempo reale

  • currency => Trasforma un numero in "soldi"
  • date => Formatta una data
  • filter => Seleziona alcuni elementi da una lista
  • json  => Trasforma un oggetto in un JSON
  • limitTo => Limita una lista o una stringa a determinati caratteri
  • lowercase => Trasforma una stringa in minuscolo
  • number => Trasforma una stringa in un numero
  • orderBy => Ordina una lista di elementi
  • uppercase => Trasforma una stringa in maiuscolo

Filters


 <!--
 $scope.price = 58;
 Output: $58.00
 -->
 <h1>Price: {{ price | currency }}</h1>


 <!--
 $scope.names = ['Rick, 'Carl', 'Daryl', 'Michonne', 'Glenn', 'Maggie'];
 Output: Dipende dal valore dell'input!
 -->

 <p>
   <input type="text" ng-model="test">
 </p>
 <ul>
   <li ng-repeat="x in names | filter:test">
     {{ x }}
   </li>
 </ul>

Esempio

Modules

I moduli dichiarano esplicitamente come una applicazione deve essere avviata

 

Possono esserci più moduli all'interno di una webapp

Possono essere indipendenti tra di loro

 
 app.module('MyModule', [
   // Lista di moduli richiesti da MyModule
 ])
 .config(function( ... ) {
   // Parte di configurazione di MyModule
 })
 .run(function() {
   // Parte prima del "run" di MyModule
 });

Controllers

I Controller sono funzioni Javascript che regolano il flusso di un determinato componente


 .controller('MyController', [
    '$scope',
    // Inseriamo qui la lista dei componenti che vogliamo caricare
    // ed utilizzare nel nostro Controller
    // Poi facciamo l'associazione dei componenti
    // tramite i parametri della funzione
   function( $scope ) {

    // Qui inseriamo la logica

   }
 ]);

Scope and RootScope

Ogni componente Angular ha il suo "scopo" (inteso come restrizione, non come funzionalità)

Scope and RootScope

Ogni componente Angular ha il suo "scopo" (inteso come restrizione, non come funzionalità)


 .controller('MyController', [
            '$scope', 
   function( $scope   ) {
    // Possiamo inserire funzioni e/o variabili

     $scope.title = 'Hello!';

     $scope.items = [
       { id: 1, name: "Test 001" },
       { id: 2, name: "Test 002" },
       { id: 3, name: "Test 003" }
     ];


    $scope.onItemClicked = function(item) {
      alert("Hai cliccato " + item.name + "!");
    };

   }
 ]);

Routing

 ...
 .config(['$routeProvider',
   function config($routeProvider) {
     $routeProvider
      .when('/home', {
        controller  : 'HomeController',
        templateUrl : 'pages/home.html'
      })
      .when('/login', {
        controller  : 'LoginController',
        templateUrl : 'pages/login.html'
      })
      .otherwise('/home');
    }
 ]);
 <body ng-app="DemoApp">
   <div ng-view></div>
 </body>

Per simulare i cambi di pagina in una SPA, abbiamo bisogno di qualcuno che lo faccia per noi,

$routeProvider è il nostro strumento

Promises: $q

Serve a rendere asincrone le funzioni

function asincrona(parametro) {
  return $q(function(resolve, reject) {
    setTimeout(function() {
      var result = sincrona(parametro);
      
      if (angular.isDefined(result)) {
        resolve(result);
      } else {
        reject('Ops, è successo qualcosa.');
      }
    }, 1000);
  });
}

var promise = asincrona(42);
promise.then(function(result) {
  alert('Success: ' + result);
}, function(reason) {
  alert('Failed: ' + reason);
});

Il miglior modo per imparare una tecnologia,

è iniziare ad usarla!

Esempio

<!DOCTYPE html>
<html>
	<head>
		<title>Inizio</title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<link rel="stylesheet" href="libs/bootstrap/dist/css/bootstrap.min.css">
		<link rel="stylesheet" href="libs/style.css">

		<!-- Importazione script -->
		<script src="libs/angular/angular.min.js"></script>
		<script src="libs/jquery/jquery.min.js"></script>

	</head>
	<body>

	<div class="container">
		<div class="row">
			<div class="col-xs-12">
				<h1>Framework VS Library</h1>
			</div>
			<div class="col-sm-6 jquery">
				<h2>jQuery</h2>
				<label>Valore</label>
				<input class="form-control valore" type="number" min="0" value="100">
				<label>%IVA</label>
				<input class="form-control iva" type="number" min="0" value="22">
				<label>Totale:</label>
				<input class="form-control totale" type="number" disabled>
			</div>

			<div class="col-sm-6" ng-app ng-init="val = 100; iva = 22">
				<h2>AngularJS</h2>
				<label>Valore</label>
				<input class="form-control" type="number" min="0" value="100" ng-model="val">
				<label>%IVA</label>
				<input class="form-control" type="number" min="0" value="22" ng-model="iva">
				<label>Totale:</label>
				<input class="form-control" type="number" disabled ng-value="((val / 100 * iva) + val).toFixed(2)">
			</div>
			<div class="col-xs-12">
				<hr>
				<p>Guardiamo bene il codice...</p>
			</div>
		</div>
	</div>


	<script>

	$(document).on('ready',function(){
		calcola();
		$('.jquery .valore, .jquery .iva').on('change',calcola);
	})

	function calcola(){
		var val = parseInt($('.jquery .valore').val());
		var iva = parseInt($('.jquery .iva').val());
		var totale = ((val / 100) * iva) + val;
		$('.jquery .totale').val(totale.toFixed(2));
	}

	</script>

	</body>
</html>

Esempio 2

<!DOCTYPE html>
<html ng-app> <!-- inizializzo AngularJS su tutta la pagina -->
	<head>
		<title>Setup AngularJS</title>

		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<link rel="stylesheet" href="libs/bootstrap/dist/css/bootstrap.min.css">
		<link rel="stylesheet" href="libs/style.css">

		<!-- Importazione script -->
		<script src="libs/angular/angular.min.js"></script>
		<!-- Traduzione i18n ITA per AngularJS -->
		<script src="libs/angular-locale_it-it.js"></script>

	</head>
	<body>

		<div class="container">
			<div class="row">
				<div class="col-xs-12">
					<h1>Setup AngularJS</h1>
				</div>
			</div>
			<div class="row">
				<div class="col-xs-12">
					<h3>Testo semplice</h3>
				</div>
				<div class="col-md-3">
					<!-- ng-model definisce un modello dati -->
					<input type="text" class="form-control" ng-model="testo">
				</div>
				<div class="col-md-3">
					<!-- {{ }} espressione data binding -->
					<p>Ciao <strong>{{testo}}</strong></p>
				</div>
				<div class="col-md-3">
					<!-- "| uppercase" è un filtro -->
					<p>Ciao <strong>{{testo | uppercase}}</strong></p>
				</div>


				<div class="col-xs-12">
					<h3>Date</h3>
				</div>
				<div class="col-md-3">
					<input type="date" class="form-control" ng-model="giorno">
				</div>
				<div class="col-md-3">
					<p>{{giorno | date:'medium'}}</p>
				</div>
				<div class="col-md-3">
					<p>{{giorno | date:'fullDate'}}</p>
				</div>

				<!-- ng-init permette di eseguire codice dopo l'inizializzazione di AngularJS -->
				<div class="col-xs-12" ng-init="valore = 42">
					<h3>Numeri</h3>
				</div>
				<div class="col-md-3">
					<input type="number" step="0.001" class="form-control" ng-model="valore">
				</div>
				<div class="col-md-3">
					<p>{{valore | number }}</p>
				</div>
				<div class="col-md-3">
					<p>{{valore | number:2}}</p>
				</div>
				<div class="col-md-3">
					<p>{{valore | currency}}</p>
				</div>


			</div>
		</div>

	</body>
</html>

AngularJS

By Claudio Bisconti