SlideShare a Scribd company logo
1 of 154
CORSO JAVASCRIPT
Basic introduction of Vanilla JS and Angular
DAY ONE - JAVASCRIPT HISTORY
JS é stato creato nel 1995 da Brendan Eich, un programmatore della Netscape.
Principalmente per sopperire all' assenza di un linguaggio che potesse interagire con i
browser e permettere di automatizzare i processi.
Successivamente In parallelo vennero sviluppati altri tentativi sullo stesso piano come JScript
e (dopo) ActionScript della Macromedia (di cui fece parte anche Einch) fino alla nascita della
specifica di Jesse James Garrett che rivoluzionó JS definendo un set di tecnologie che
facessero da spina dorsale per le future implementazioni del linguaggio e portó all' avvento di
AJAX . Da quel punto in poi la community é stata molto attiva producendo migliaia di librerie
tra cui Jquery, Prototype e Dojo.
Si istituirono altre fondazioni open source che avevano come obiettivo quello di sviluppare
una libreria standard per lo sviluppo su javascript fuori dal contesto del browser da cui
nacque Node.js
DAY ONE - JAVASCRIPT HISTORY
1995: At Netscape, programmer Brendan Eich created "JavaScript".
1996: Microsoft releases "JScript", a port for IE3.
1997: JavaScript was standardized in the "ECMAScript" spec.
2005: "AJAX" was coined and the web 2.0 age begins.
2006: jQuery 1.0 was released.
2010: Node.JS was released.
2015: ECMAScript 6 was released.
DAY ONE - VARIABILI
Variabili
Le variabili sono "contenitori di dati" generici (non tipizzati)
Dichiarazione: var, let or const (since ES6)
Scope: Global, Local (aka Function Scope)
Data Types
Variabili implicite: this, arguments [window e console (solo su client)]
DAY ONE - VARIABILI
Tipi di dati
null var x = null;
undefined var x;
Number var x = 1; var y = new Number(1);
Boolean var x = false; var y = new Boolean(expression)
String var x = "John"; var y = new String("Jack");
Date var x = new Date(2018, 1, 1, 10, 33, 30); var y = new Date(milliseconds)
Array var x = ["el1", "el2"]; var y = new Array();
Object var x = {firstName: "John", lastName: "Doe"}; var y= new Boolean();
Regexp var x = /ab+c/; var y = new RegExp("ab+c");
Function var x = function(a, b) {return a+b;}
var y = new Function("a", "b",
"return a+b;");
Symbol var x = Symbol();
DAY ONE - VARIABILI
Hoisting: Declare Your Variables on top
“Thanks to the Hoisting a variable can be used before it
has been declared. (except let and const variables)”
x = 5; //assignment
doSomethingWithX(x); //using variable before initialization
var x; //declaration
Lo stesso vale per le funzioni
DAY ONE - VARIABILI
One statement, many variables
var a, b, c=1; // a e b sono undefined, c é uguale a 1
var a=b=c=1; // a, b e c valgono 1;
Ridichiarazione
var a = 1;
var a;
console.log(a); // a vale ancora 1;
Migrazione da var (old ES versions) a let/const
var a = 1; // vecchia sintassi
let a = 1; // variabili che possono mutare il valore dopo la dichiarazione
const a = 1; // variabili che non possono mutare il proprio valore dopo la dichiarazione
DAY ONE - VARIABILI
Type Coercion
“Type coercion is the process of converting value from
one type to another (such as string to number, object to
boolean, and so on). Any type, be it primitive or an
object, is a valid subject for type coercion. To recall,
primitives are: number, string, boolean, null, undefined +
Symbol (added in ES6).”
DAY ONE - VARIABILI
Type Coercion
true + false ====> 1
true + true ====> 2
12 / "6" ====> NaN
"number" + 15 + 3 ====> "number153"
15 + 3 + "number" ====> "18number"
"foo" + + "bar" ====> "fooNaN"
'true' == true ====> false
false == 'false' ====> false
false == '' ====> true
[] + null + 1 ====> "null1"
{}+[]+{}+[1] ====> "[object Object][object Object]1"
DAY ONE - OPERATORS
Gli operatori sono simboli che permettono di assegnare, comparare e modificare
valori in una variabile o condizione
Si suddividono in Assignment, Conditional, Logical, Bitwise
Altri operatori speciali:
- delete,
- typeof,
- instanceof
- in (usato nei loop for)
- void
DAY ONE - OPERATORS
Operatori Aritmetici (e non)
Simbolo Descrizione
= Assegnazione variabile
+
Addizione numerica/Concatenazione stringhe o oggetti/Unario più (tenta
la conversione in numerico dell' oggetto)
* Moltiplicazione
/ Divisione
% Resto
--
Assegnazione e decremento (di variabile)
++ Assegnazione e incremento (di variabile)
DAY ONE - OPERATORS
Operatori comparativi
Logical operators implement lazy evaluation
Gli operatori sono pressoché identici (==, !=, >, <, >=, <=, &&, ||) a quelli Java con la
differenza tra strict/loose comparison
0==''; //loose comparison, returns true
0===''; //strict comparison, returns false
Nonostante la strict comparison si possono commettere errori
true + true === 2 //true
true === 1 // false (hopefully)
DAY ONE - OPERATORS
Operatori comparativi
Operatore Ternario
( condition ) ? then : else
var message = age > 18 ? "Adult" : "Too young";
a differenza di Java, posso eseguire un ternario senza assegnazione
age > 18 ? doThis() : doThat();
DAY ONE - DATA TYPES
Data types
Le strutture di dati sono il building block per le tipologie di oggetti definibili nelle
variabili
Primitivi (immutabili): null, undefined, string, Boolean, number, Symbol
Oggetti (referenced): Date, Array, Object, Function
DAY ONE - DATA TYPES
Numbers e Aritmetica
I numeri includono particolari numeri speciali
Positive infinity -> Number.POSITIVE_INFINITY
Negative infinity ->Number.NEGATIVE_INFINITY
NaN (not a number)
Il numero massimo di decimale é 17, e l' aritmetica sui numeri a virgola mobile non é accuratissima!
var x = 0.1+0.2; // x will be 0.30000000000000004, what a mess!!
var x = ((0.1*10)+(0.2*10))/10; // x now will be 0.3
Don't mess with mixed data types
console.log(1+2+3) --> 6
console.log("5"+2+3) --> 523
console.log(2+3+"5") --> 55
DAY ONE - DATA TYPES
Numbers e Aritmetica - Math
Math é un oggetto implicito di utility per svolgere operazioni aritmetiche. Contiene
fondamentali metodi e costanti per il calcolo, qualche esempio:
Math.PI pigreco
Math.abs(n) valore assoluto di un numero
Math.pow(n, p) potenza di p di un numero n
Math.min(n, n1..nx)/Math.max(n,n1..., nx) ritorna il numero maggiore/minore tra i
parametri in ingresso
.... e molto altro (random, round, sin, acos)
DAY ONE - DATA TYPES
Strings
Le stringhe sono variabili primitive (single/double quoted), tuttavia possiedono diversi metodi e
proprietá e funzioni tra cui:
length ritorna la lunghezza della stringa
indexOf ritorna l' indice numerico della prima occorrenza di un testo specifico all' interno di una
stringa
slice/substring/substr seppure con sottili differenze tutte e tre tagliano una stringa dati i due
estremi posizionali
replace sostituisce le occorrenze di un testo specifico (o regexp) con un altro testo
toUpperCase/LowerCase il nome dice tutto
Honorable mentions: charAt, trim, concat e molto altro!
DAY ONE - DATA TYPES
Objects
Gli oggetti sono normalmente definiti come literals i cui valori vengono espressi
come mappa chiave:valore:
let car = {
name: "Saturn", // a property containing a string
getCar: function() {...}, // a property containing a function
nestedCar: { // a property containing a nested object
nestedName: "nestedValue"
}
}
per accedere alla property nestedName si segue il path dell' oggetto
car.nestedCar.nestedName oppure car["nestedCar"]["nestedName"]
DAY ONE - DATA TYPES
Objects - Metodi del costruttore Object
Object, oltre ad essere istanziabile (creando un nuovo oggetto) puó essere
utilizzato attraverso i metodi del costruttore (senza istanza) che contengono
funzioni fondamentali nello sviluppo, di seguito i metodi piú utilizzati nello sviluppo:
Object.create(obj) ritorna un nuovo oggetto dal prototipo di obj
Object.keys(obj) ritorna un array contenente le property names di obj
Object.assign(obj): ritorna un nuovo oggetto copiando tutte le prop di obj
altri metodi sperimentali e non come Object.is, Object.freeze, Object.observe
DAY ONE - DATA TYPES
Dates
Gli oggetti Date rappresentano un singolo momento nel tempo
Costruzione di una istanza dell' oggetto
new Date(); //date based on client system settings current time (with TZ)
new Date(value); //current time in millis
new Date(dateString); //try parsing a date from a string
new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]); //using single fields,
omitted ones are setted by default to 0
//date valide
var today = new Date();
var birthday = new Date('December 17, 1995 03:24:00');
var birthday = new Date('1995-12-17T03:24:00');
var birthday = new Date(1995, 11, 17);
var birthday = new Date(1995, 11, 17, 3, 24, 0);
DAY ONE - DATA TYPES
Dates - Formattazione
toString: il metodo di default formatta la data in base al locale impostato sulle
impostazioni del sistema del client
Sun Sep 16 2018 16:00:43 GMT+0200 (Central European Summer Time)
toLocaleDateString fornisce una variante con cui visualizzare una data in base al
locale e la timezone
console.log(event.toLocaleString('en-GB', { timeZone: 'UTC' }));
20/12/2012, 03:00:00
Non é possibile specificare un date format pattern nativamente, per questo ed altri
motivi si utilizzano librerie specifiche per la manipolazione e formattazione di date
(moment)
DAY ONE - DATA TYPES
Dates - Getters e setters
É possible recuperare e impostare i singoli valori di una data attraverso funzioni getter & setter.
getFullYear()/setFullYear(n) //anno (locale) 4 digits
getMonth()/setMonth(n) 0-11
getDate()/setDate(n) //giorno del mese - 1-31
getDay()/setDay(n) //giorno della settimana -0-6
getHours()/setHours(n) //ora locale 0-23
getMinutes()/setMinutes(n) //minuti 0-59
getSeconds()/setSeconds(n) //secondi 0-59
getMilliseconds()/setMilliseconds(n) //millis 0-999
getTime()/setTime(n) //millisecondi dal 1 gennaio 1970
per la lista completa consultare
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
DAY ONE - DATA TYPES
Arrays
Un array é una lista di oggetti a cui é possibile accedere tramite un indice
let fruits = ["Apple", "Banana", "Orange"];
console.log(fruits[1]); // prints Banana
DAY ONE - DATA TYPES
Arrays
Per aggiunta/rimozione di valori:
push aggiunge uno o piú elementi in coda all'array
fruits.push("Watermelon"); //fruits contains ["Apple", "Banana", "Orange", "Watermelon"]
pop rimuove l'ultimo elemento dalla coda dell'array (ritorna l' elemento stesso)
fruits.pop(); //fruits contains ["Apple", "Banana"]
shift rimuove il primo elemento dalla testa dell' array (ritorna l' elemento stesso)
fruits.shift(); //fruits contains ["Banana", "Orange"]
unshift aggiunge uno o piú elementi dalla testa dell' array
fruits.unshift("Watermelon"); //fruits contains ["Watermelon", "Apple", "Banana", "Orange"]
DAY ONE - DATA TYPES
Arrays
per alterare il valore di un elemento esistente é sufficiente assegnarlo tramite indice
fruits[1] = "Pear"; // fruits contains ["Apple", "Pear", "Orange"];
Altri metodi fondamentali:
join(separator): converte l' array in una stringa con valori separati da separator
fruits.join(" * ");// "Apple * Banana * Orange"
splice(idx, nElem) ritorna un nuovo array rimuovendo nElem elementi iniziando da idx
fruits.splice(0, 2);// ["Apple", "Banana"] NB: l' array stesso é cambiato!
slice(idxStart,idxEnd) ritorna un nuovo array contenente gli elementi compresi tra idxStart e
idxEnd
fruits.slice(0, 2);// ["Apple", "Banana", "Orange"] NB: l' array non é cambiato!
DAY ONE - DATA TYPES
Arrays - Manipolazione massiva
Le tre principali funzioni per scorrere un array sono
map rimappa un array in un altra lista, i cui valori sono determianti da una funzione in ingresso a cui viene
passato ogni singolo elemento
let numbers = [1, 3, 6];
let pow = numbers.map(function(item) { return item*item;}); // pow conterrá le potenze dell' array iniziale
filter ritorna un sottoinsieme dell' array i cui elementi soddisfino le condizioni della funzione passata in input
let numbers = [1, 3, 6, 17, 22];
let filtered = numbers.filter(function(item) { return item < 10}); //filtered conterrá solo gli elementi i cui valore é piú basso di 10
reduce trasforma un array in un altro oggetto (passato in input come secondo parametro) ciclando ogni
elemento
let numbers = [1, 3, 6, 17, 22];
let total = numbers.reduce(function(total, item) { return total+item}, 0); //total = 49
la funzione in ingresso prende per primo parametro l' accumulatore (oggetto che di volta in volta viene ritornato), l'
elemento N dell' array, l'indice dell' elemento (opzionale), l' array stesso che contiene l' elemento
DAY ONE - DATA TYPES
Regular expressions
Una regular expression é un' automa per la ricerca di pattern all' interno di una stringa.
let re = /world/;
console.log(re.test("Hello world!!")); // returns true;
console.log(re.test("Hello word")); // returns false;
possono essere molto potenti e utilizzate per validazioni di campi o per estrarre particolari campi da
stringhe di cui conosciamo la struttura. Esempio di regular expression di validazione di un codice fiscale:
let reCf = /^(?:(?:[B-DF-HJ-NP-TV-Z]|[AEIOU])[AEIOU][AEIOUX]|[B-DF-HJ-NP-TV-Z]{2}[A-Z]){2}(?:([dLMNP-V]){1}(?:([dLMNP-V]){1}(?:[w]{1,2}|([A-
EHLMPR-T](?:[04LQ][1-9MNP-V]|[1256LMRS][dLMNP-V])|[DHPS][37PT][0L]|[ACELMRT][37PT][01LM])(?:[w]{1,3}|([A-MZ][1-9MNP-V][dLMNP-V]{2}|[A-
M][0L](?:[1-9MNP-V][dLMNP-V]|[0L][1-9MNP-V]))([A-Z]){0,1}){0,1}){0,1}){0,1}){0,1}$/i;
var isValidCf = reCf.test("RSSMRA90R11F205H"); // returns true if it is a valid CF
Il mondo delle RegExp é vasto, comprende flags, sets di caratteri, sistemi di raggruppamento e molto
altro. Per saperne di piú: https://javascript.info/regular-expressions
DAY ONE - DATA TYPES
Functions
Le funzioni sono blocchi di codice (routines) che eseguono particolari tasks.
Una funzione viene attivata tramite chiamata (call) da parte di "qualcuno".
Le funzioni sono oggetti, in quanto tali possono essere assegnate alle
variabili, passate come parametro, essere un valore di ritorno di una funzione
DAY ONE - DATA TYPES
Functions Invocation
Definita una funzione
function doSomething(a, b) {
return a*b;
}
possiamo usare strategie diverse di invocazione:
1 - doSomething(10, 3);
2 - doSomething.call(null, 10, 3)
3 - doSomething.apply(null, [10, 3])
DAY ONE - DATA TYPES
Functions - Call & Apply
nei casi di call e apply il primo parametro della funzione é l' oggetto di contesto.
La keyword this che si riferisce all' oggetto di contesto con cui é stata invocata la
funzione
function doSomething() {
return this.firstName + " " + this.lastName;
}
var person = {firstName: "John", lastName: "Doe"};
doSomething.call(person);
doSomething.apply(person);
//in both cases return is John Doe"
DAY ONE - DATA TYPES
Functions - Types
Declared
function functionName(parameters) {
//do something;
}
Anonymous (self invoking function)
(function(parameters) {
//do something;
}());// note the parenthesis at the end and wrapping the function
Function expression (a function expression is stored in a variable)
var myFunction = function(parameters) {
//do something;
}
myFunction(myParam1, myParam2, myParamX); // function call
DAY ONE - DATA TYPES
Functions - Arrow (ES6)
Le funzioni a freccia é una sintassi piú compatta della definizione di una funzione
Il seguente codice:
var myFunction = (aString) => aString.length;
é equivalente a:
var myFunction = function(aString) => {
return aString.length;
}
la compattazione del codice é evidente nella manipolazione degli array
let materials =["Hydrogen","Helium", "Lithium","Beryllium"];
let materialLength = materials.map(item => item.length); // [8, 6, 7, 9]
DAY ONE - DATA TYPES
typeof & instanceof
Sono due keyword per testare se una variabile contiene una certo tipo di dato
Usando typeof otteniamo la rappresentazione in formato stringa del tipo di oggetto
typeof 'example string' == 'string'; // true
Usando instanceof si compara il Type con cui é stato dichiarato in fase di costruzione
[] instanceof Array; // true
Usa typeof per le variabili primitive, instanceof per gli oggetti complessi
var MyClass = function () {};
var instance = new MyClass();
typeof instance; // object
instance instanceof MyClass; // true
DAY ONE - DATA TYPES
ES6 Features - Notable mentions
String template literals
var first ="John";
var last = "Doe";
var name = `Your name is ${first} ${last}.`;
Default parameters value
var link = function(height = 50, color = 'red', url = 'http://loremipsum.com') {
...
}
Spread operator ( ... )
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);
DAY ONE - EXERCISES
Let's try it...
What is the value of the hello variable in the following expression?
var hello;
DAY ONE - EXERCISES
Let's try it...
What is the value of the hello variable in the following expression?
var hello; ===> undefined
DAY ONE - EXERCISES
Let's try it...
What does the following expression return?
var x = 3 / "bob";
DAY ONE - EXERCISES
Let's try it...
What does the following expression return?
var x = 3 / "bob"; ===> NaN
DAY ONE - EXERCISES
Let's try it...
What is the result of "80" + 71.2:
A - 151.2
B - 151
C - "8071.2"
DAY ONE - EXERCISES
Let's try it...
What is the result of "80" + 71.2:
A - 151.2
B - 151
C - "8071.2"
C - "8071.2"
DAY ONE - EXERCISES
Let's try it...
What is the result of 2 +"2":
A - 4
B - "4"
C - "22"
DAY ONE - EXERCISES
Let's try it...
What is the result of 2 +"2":
A - 4
B - "4"
C - "22"
C - "22"
DAY TWO - STATEMENTS
Statements
Gli statements eseguono istruzioni, assegnazioni, dirigono i flussi sui diversi
blocchi di codice
Conditional statements: if/else/else if, switch
Loop statements: for, while, do..while
Error handling: try/catch/finally
DAY TWO - STATEMENTS
if/else if/else Statement
if é la keyword per descrivere un flusso di azioni in base a condizioni differenti
if (condition) {
block of code to be executed if the condition is true
}
else é la keyword per definire il blocco di codice da eseguire se la condizione di if é false
if (condition) {
block of code to be executed if the condition is true
} else {
block of code to be executed if the condition is false
}
else if é la keyword per definire una nuova condizione nel caso la if non sia stata soddisfatta
if (condition) {
block of code to be executed if the condition is true
} else if (condition2) {
block of code to be executed if the condition is false and condition2 is true
}
DAY TWO - STATEMENTS
while/do while Statement
while é la keyword per descrivere un flusso di azioni iterate finché la condizione non é
false
while (condition) {
block of code to be executed till condition become false
}
do é la keyword, unita a while (in coda), che descrive il medesimo flusso, la
differenza é che la prima iterazione viene eseguita sempre.
do {
i will be executed at least 1 time!
block of code to be executed till condition become false
} while (condition);
DAY TWO - STATEMENTS
for Statement
for é la keyword per descrivere un flusso di azioni iterate un numero definito di volte:
for (var i=0; i < heroes.length; i++) {
console.log(heroes[i].name); //prints all heroes names from the array
}
for...in é una sintassi per ciclare le properties su un oggetto
var hero = {name: "Batman", superpower: "Richness"};
for (x in hero) {
console.log(x+"="+hero[x]); //prints all properties and values of hero object
}
DAY TWO - STATEMENTS
switch Statement
switch - case é la keyword per indirizzare in un blocco di codice basandosi sul valore di una variabile
switch (hero.name) {
case "Batman":
takeBatMobile();
break;
case: "Superman":
useSuperSpeed();
break;
default: break;
}
break é la keyword con cui si esce dal blocco case (evita di eseguire altri test sullo switch e ottimizza)
default é la keyword all' interno dello switch per definire il blocco di codice da eseguire se nessuno dei
case é soddisfatto
DAY TWO - STATEMENTS
try/catch/finally/trow Statement
try/catch definisce un blocco di codice con eccezione controllata
try {
someRiskyFunction();
} catch(e) {
console.log(e);
}
throw é l' istruzione che permette di rilanciare un errore
throw "Error2"; // String type
throw 42; // Number type
throw true; // Boolean type
throw {toString: function() { return "I'm an object!"; } };
finally definisce un blocco di codice che verrá eseguito indipendentemente dall' esito all' interno della try/catch
try {
someRiskyFunction();
} catch(e) {
console.log(e);
} finally {
console.log("This block will be executed in any case");
}
DAY TWO - BUILTIN FEATURES
Scope
Lo scope di una variabile definisce il livello di appartenenza della stessa all' interno
del flusso di codice
Local scope: l' accesso alla variabile é ristretto all' interno di un blocco di codice
Global scope: l' accesso é garantito su tutti i blocchi di codice
Una variabile definita in una funzione é accessibile da una sua sottofunzione
DAY TWO - BUILTIN FEATURES
Scope
Globale
var i = 5; // is accessible inside functions, but everyone can access and change it
function doSomething() {
return i*2;
}
Locale
function doSomething() {
var i = 5; // i is accessible only inside this function
return i*2;
}
Nested Function
function doSomething() {
var i = 5; // i is accessible inside this function and its subfunction
function doSomethingElse() { return i*2; }
doSomethingElse();
return i;
}
DAY TWO - BUILTIN FEATURES
Closure
“Una closure è quello che una funzione è capace di ricordare del contesto (lexical
scope) dalla quale proviene, anche se viene eseguita al di fuori di esso.”
Permette di isolare il contesto di variabili
DAY TWO - BUILTIN FEATURES
Closure
Per isolare una variabile, al fine di renderla accessibile solo all' interno di un contesto e
mantenendo il suo stato, usiamo le Function Closure sfruttando le self invoking functions:
var counterFunction = (function() {
var counter = 0;
return function() {
return ++counter;
}
}());
La funzione viene invocata nel momento in cui viene definita la variabile counterFunction, in
questo modo possiamo invocare counterFunction() che ritornerá il valore incrementato di
counter
console.log(counterFunction()); // returns 1
console.log(counterFunction()); // second time, returns 2
DAY TWO - BUILTIN FEATURES
Prototypes
Un oggetto puó ereditare (o estendere) un altro oggetto (che fa da prototipo)
Non é consigliabile estendere i tipi di base (js versions conflicts and many more
issues!)
Old ways vs New Ways (ECMAScript 2015)
DAY TWO - BUILTIN FEATURES
Prototypes - the old way
Prima dell' avvento delle “classes”, per creare un oggetto:
function Cat(name) {
this.name = name;
this.meow = function () {
return this.name + " meow !";
}
}
var cat = new Cat("Garfield");
console.log(cat); // prints Cat { name:'Garfield'}
console.log(cat.meow()); //prints "Garfield meow !"
Problemi con le "new"?
var cat = Cat("Garfield"); // error! this is undefined
console.log(cat);
DAY TWO - BUILTIN FEATURES
Prototypes - the old way
Estendere un oggetto con prototype
function Animal(name) {
this.name = name;
}
Animal.prototype.constructor = Animal;
Animal.prototype.speak = function () {
return "My name is " + this.name;
};
function Cat(name) {
Animal.call(this, name); //call super constructor Animal
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
cat = new Cat("Garfield");
console.log(cat.speak());// prints "My name is Garfield"
DAY TWO - BUILTIN FEATURES
Prototypes - the old way
La proprietá __proto__ é un accessor di Object.prototype che permette di definire
anch'esso il prototipo di un oggetto che si vuol creare. É una feature deprecata e
comporta varie issue di performance
Estendere un oggetto con __proto__
var Animal = function() {
}
var cat = {};
var animal = new Animal();
car.prototype.__proto__ = animal; //DO NOT USE
Un modo migliore é l' utilizzo di Object.create
var cat = Object.create(animal); //extends properties and methods of animal, without affecting the "animal" variable
DAY TWO - BUILTIN FEATURES
Prototypes - the new way
Introdotto il concetto di “classi”
Codice piú pulito e senza fraintendimenti sulla variabile this
Piú object oriented
DAY TWO - BUILTIN FEATURES
Prototypes - the new way
Estendere un oggetto
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return "My name is " + this.name;
}
}
class Cat extends Animal {
constructor(name) {
super(name);
}
}
let cat = new Cat("Garfield");
cat.speak();
DAY TWO - BUILTIN FEATURES
Timeouts - postponing execution
Il timeout é una funzionalitá (praticamente una function) built-in sul browser.
Permette di ritardare l'esecuzione della function passata come parametro
É possibile cancellare l' esecuzione (se si ha necessitá di farlo)
Esempio:
let myFunction = function () {
console.log("Hello!");
};
var timeoutId = setTimeout(myFunction, 1000); //prints "Hello!" after 100 milliseconds
//clearTimeout(intervalId); // uncomment this if you want to stop the timeout execution
DAY TWO - BUILTIN FEATURES
Interval - repeating Timeouts
L' interval permette di eseguire funzioni a intervalli regolari di tempo, é di fatto un timeout ripetuto
É possibile cancellare la schedulazione dell' intervallo (se si ha necessitá)
Esempio:
let myFunction = function () {
console.log("Hello!");
};
var intervalId = setInterval(myFunction, 100); //prints "Hello!" at intervals of 100 milliseconds, forever and ever...
//clearInterval(intervalId); //uncomment if you want to stop the interval, otherwise it will keep going
DAY TWO - BUILTIN FEATURES
Callbacks
Una callback (o higher-order function) é un design pattern che prevede
una funzione passata come parametro (argument) ad un' altra funzione ed
eseguita in un determinato momento da quest' ultima;
Sono soprattutto utili in caso di funzioni asincrone (il risultato non é disponibile
al momento dell' uscita dalla funzione invocata), come Timeouts, Intervals o le
Promises che verranno trattate piú avanti
DAY TWO - BUILTIN FEATURES
Callbacks
Esempio di callback
function doSomethingAndNotify(a, b, fnCB) {
var computed = a + b;
var options = {computedValue: computed};
setTimeout(function () {
fnCB(options);
}, 100);
}
doSomethingAndNotify(1, 2, function (options) { //this is my callback fnCB!!!
console.log(options.computedValue); // prints the resulting computation, well done!
});
DAY TWO - BUILTIN FEATURES
Promises
Una Promise é un oggetto che rappresenta l' eventuale completamento di un task asincrono
Native da ECMAScript 6
Ha un costruttore con una funzione che prende due parametri in ingresso:
resolve completamento riuscito
reject completamento fallito
L'esito del task asincrono é gestibile attraverso due metodi:
then prende in input una funzione di callback per il completamento riuscito
catch prende in input una funzione di callback per il completamento fallito
La funzione di callback di completamento riuscito puó ritornare un' altra promise o un
oggetto, permettendo il chaining di piú Promises
DAY TWO - BUILTIN FEATURES
Promises Native
Esempio di una Promise nativa
let heroes = [{name: "Batman"}, {name: "Robin"}];
let findHeroesNames = function () {
return new Promise((resolve, reject) => {
if (heroes) resolve(heroes.map(item => item.name)); else reject(heroes);
});
};
findHeroesNames().then(function (heroes) {
console.log(heroes); //prints an array ["Batman", "Robin"]
}).catch(function (err) {
console.log("Something went wrong here: " + err);
});
DAY TWO - BUILTIN FEATURES
Promises - Chaining
Il Chaining permette di avere delle operazioni asincrone a catena, eseguite una dopo l' altra
Esempio di una Promise chain
let heroes = [{name: "Batman", superpower:"Cleverness"}, {name: "Robin", superpower: "Friend of Batman"} ];
let findHeroes = function() {
return new Promise(resolve, reject) {
if (heroes) resolve(heroes);
else reject(heroes);
}
}
findHeroesNames().then(function(heroes) {
console.log("I've got "+ heroes.length+" heroes"); //prints the array of heroes object
return heroes.map(item => item.supepower); // could return another async operation
}).then(function(heroesPowers) {
console.log(heroesPowers); //prints ["Cleverness", "Friend of Batman"]
}).catch(function (err) {
console.log("Something went wrong here: "+err);
});
DAY TWO - BUILTIN FEATURES
Promises - Branching
Il branching aggancia la stessa promise a multipli callback (invocati parallelamente)
Esempio di una Promise Branch
let heroes = [{name: "Batman", superpower:"Cleverness"}, {name: "Robin", superpower: "Friend of Batman"} ];
let findHeroes = function() {
return new Promise(resolve, reject) {
if (heroes) resolve(heroes);
else reject(heroes);
}
}
let findPromise = findHeroesNames();
findPromise.then(function(heroes) {
console.log("I've got "+ heroes.length+" heroes");
return heroes.map(item => item.supepower);
});
findPromise.then(function(heroes) { // still receiving heroes instead of heroes name!!!
console.log(heroes);
});
66
DAY TWO - ECMASCRIPT6 MODULES
Importing and Exporting
Nella vecchia concezione di client javascript per utilizzare variabili attraverso vari files
occorreva definire variabili globali, causando la proliferazione di oggetti sparsi su tutta l'
applicazione di cui quasi non era possibile determinare l' origine e avendo come vincolo l'
ordine specifico dei file da importare su browser
La community JS ha generato negli anni varie soluzioni per ovviare al problema creando degli
standard che definiscono i meccanismi di modularizzazione. I piú importanti sono
1. Asynchronous Module Definition (AMD) : implementato da RequireJS
2. CommonJS Modules: implementato in Node.js
I moduli introdotti in ES6 sono un' evoluzione dei 2 principali contendenti, racchiudono le
migliori caratteristiche e ne riducono i difetti.
67
DAY TWO - ECMASCRIPT6 MODULES
Importing and Exporting
The Exports keyword
// lib.js
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
Possiamo ora importare le funzioni in un altro file senza infarcire di variabili l'
applicazione
68
DAY TWO - ECMASCRIPT6 MODULES
Importing and Exporting
The Import keyword
// main.js
import { square, diag } from 'libs'; // picking some exports from lib
import * as lib2 from 'lib2'; // importing all exports from lib2, with alias
console.log(square(11)); // square is available from lib
console.log(diag(4, 3)); // also diag is available
console.log(lib2.whateverMethod());// using whateverMethod from lib2
Questo sistema rende piú pulito, ordinato e gestibile il progetto
Possiamo esportare in modo totalmente flessibile classi, variabili e funzioni
69
DAY TWO - EXERCISE
Let's try it...
Scrivere una funzione che converta un numero intero in un array che per ogni
elemento contiene una cifra del numero. es:
digitize(123) output --> [1,2,3]
digitize(1230) output --> [1,2,3,0]
DAY TWO - EXERCISE
Let's try it...
Scrivere una funzione che converta un numero intero e restituisca un array che per
ogni elemento contiene una cifra di tale numero. es:
digitize(123) output --> [1,2,3]
digitize(1230) output --> [1,2,3,0]
Soluzione
const digitize = n => [...`${n}`].map(i => parseInt(i));
DAY THREE - TYPESCRIPT
Typescript
Angular é scritto in questo linguaggio, é un superset di javascript che permette strutture tipizzate
nello stile OO (classi e interfacce). Il maggior beneficio é la facilitazione nel supporto degli ambienti
di lavoro, error spotting e type checking che finora con javascript risultavano parziali e imprecisi.
Esempio di sintassi per un' interfaccia (in questo caso un' entitá)
interface GreetingSettings {
greeting: string;
duration?: number; //nullable properties have question mark
color?: string;
}
let MyGreet: GreetingSettings = {greeting: "Hello", duration: 10, color:blue};
DAY THREE - TYPESCRIPT
Typescript
Sintassi di dichiarazione di variabili
[accessor] [identifier] : [type-annotation] = [value];
sia l' annotazione del tipo che il valore sono opzionali, omettendo la type
annotation il tipo sará any (non consigliato), omettendo il valore la variabile é
inizializzata a undefined.
private x: Widget = getWidget(1);
Sintassi di dichiarazione di una funzione
[accessor] [identifier]( [argumentName]: [argumentType] ): [type-annotation];
DAY THREE - TYPESCRIPT
Typescript - Interfaces and classes
interface Drivable {
start(): void;
drive(distance: number): boolean;
}
class Car implements Drivable {
private _isRunning: boolean;
constructor() {
this._isRunning = false;
}
public start() {
this._isRunning = true;
}
public drive(distance: number): boolean {
if (this._isRunning) {
return true;
}
return false;
DAY THREE - TYPESCRIPT
Typescript - Interfaces and classes
Un parametro dichiarato nel costruttore diventa una proprietá della classe
export class Hero {
constructor(
public id: number,
public name: string,
public power: string,
public alterEgo?: string
) { }
stringify(): string {
return this.id + "-"+this.name; //properties into this object
DAY THREE - TYPESCRIPT
Typescript - Using a type variable
Data una semplice classe
class Hero {
id: number;
name: string;
}
dichiariamo e inizializziamo la variabile
hero: Hero = { id: 1, name: "Batman"};
oppure:
hero: Hero = new Hero();
DAY THREE - TYPESCRIPT
Typescript - Features
Overloading functions
public getWidget(n: number): Widget;
public getWidget(n: string): Widget;
Type Alias
type GreetingLike = string | (() => string) | MyGreeter;
private greet(g: GreetingLike): void;
DAY THREE - TYPESCRIPT
Typescript - Features
Namespaces Per organizzare le classi in diversi contesti
namespace GreetingLib.Options {
// Refer to via GreetingLib.Options.Log
interface Log {
verbose?: boolean;
}
interface Alert {
}
}
DAY THREE - ANGULAR
Angular - A beginner guide
79
DAY THREE - ANGULAR
Angular - A beginner guide
Angularjs (1.x), Angular 2, 4, 5 or 6??
80
DAY THREE - ANGULAR OVERVIEW
Angular - Overview
Angular é un framework per sviluppare applicazioni client (browser) single page che
riunisce i migliori design pattern della storia di javascript in un' unica soluzione
Modules: i moduli di angular (NgModules) definiscono un contesto di compilazione di un
set di componenti dedicati a un particolare dominio applicativo.
Components: i componenti controllano una parte dello schermo e separano la logica di
presentazione dall' aspetto grafico dell' app, assumendo il compito di
Controller/ViewModel nel modello MVVM
Services: i servizi sono una categoria di oggetti iniettabili sui componenti e progettati per
eseguire specifici task. Permettono ai componenti di occuparsi della sola logica di
visualizzazione rendendoli piú efficienti e semplificati
81
DAY THREE - ANGULAR OVERVIEW
Angular - Overview
Directives: come i componenti, si occupano di cambiare l' aspetto della parte DOM
di cui sono responsabili
Templates: utilizzati dai components, i template rappresentano l' aspetto grafico dell'
applicazione, ossia la View sul modello MVVM
Injector: é un elemento fondamentale di Angular, che si preoccupa di fornire i servizi
ai componenti in modo dichiarativo
82
DAY THREE - ANGULAR OVERVIEW
Angular - Brief FUNDAMENTALS of MVVM
É un pattern architetturale che si propone la separation of concerns, ossia che ogni
categoria di elementi costituenti un software svolgano determinati e precisi compiti. Si
compone di:
Model: é il modello di dominio (o una sua derivazione), ció che rappresenta la struttura
di dati che si vuole visualizzare e gestire.
View: la vista rappresenta il layout e la user experience dell' app. Non dovrebbe
contenere logica se non strettamente collegata all' aspetto grafico di cosa vede l'utente
View-Model: é l' intermediario tra il modello di business e il modello.
“Il view-model fornisce quindi i dati dal modello in una forma che la vista può usare
facilmente.”
DAY THREE - ANGULAR OVERVIEW
Angular - Ecosystem
Angular Cli (former DevKit) sistema comprensivo per lo sviluppo, gestione e
deploy dei progetti
Node.js[v8+] and npm server js e package manager per installare librerie di
progetto
TypeScript un linguaggio tipizzato che compila in javascript
Jasmine/Protractor framework per test unitari e e2e
.....continua
DAY THREE - ANGULAR OVERVIEW
Angular - Ecosystem
TypeScript il nuovo linguaggio tipizzato che compila in js
Webpack 4 il tool per la build e packaging
Angular Cli (former DevKit) sistema comprensivo per lo sviluppo, gestione e
deploy dei progetti
Node.js[v8+] and npm server js e package manager per installare librerie di
progetto
Jasmine/Protractor framework per test unitari e e2e
DAY THREE - ANGULAR ARCHITECTURE
Architettura del flusso dei componenti
DAY THREE - ANGULAR ARCHITECTURE
Anatomia di un NgModule
DAY THREE - ANGULAR ARCHITECTURE
NgModule
Un modulo Angular racchiude, dichiara e rende disponibili componenti e servizi.
Dichiarazione dei metadati (decoration):
imports [] dichiarazione di tutti i moduli che si vogliono utilizzare
exports [] componenti e servizi visibili all' esterno del modulo
declarations [] componenti che il modulo utilizza
bootstrap [] il componente root che angular inizializza nel file index.html
DAY THREE - ANGULAR ARCHITECTURE
Data binding
Business Logic
(TypeScript)
Template View
(usually HTML)
SYNCHRONIZATION
DAY THREE - ANGULAR ARCHITECTURE
Data binding
Interpolation Binding (One-way component-to-view)
<p>4 + 4 = {{4+4}}</p>
<p>My favourite hero is {{hero.name}}</p>
Property Binding/Attribute/Css Class (One-way component-to-view)
<img [src]="product.imageUrl" [title]='product.productName'/>
<th [attr.colspan]="2" class="txtcenter"></th>
<td [class.txtright]="{{booleanExpression}}">Hero Details</th>
DAY THREE - ANGULAR ARCHITECTURE
Data binding
Event Binding (One-way view-to-component)
<button (click)="updateProduct()">
Update
</button>
Two-Way Binding
<input type="text" [(ngModel)]="firstName">
DAY THREE - ANGULAR ARCHITECTURE
Pipes (operatore | )
I Pipes sono disegnati allo scopo di trasformare i valori degli oggetti (piú complessi di
Number, String) in un formato rivolto alla visualizzazione dei dati su schermo.
Esempio di una pipe built in per trasformare le Date sulla view di un componente:
<p>Your birthday is {{ birthday | date }}</p> //formato di default
<p>Your birthday is {{ birthday | date:"MM/dd/yy" }} </p>//formato specifico
DAY THREE - ANGULAR ARCHITECTURE
Pipes(operatore | ) - Built-in
DatePipe
{{ value_expression | date [ : format [ : timezone [ : locale ] ] ] }}
UpperCasePipe,
{{ value_expression | uppercase }}
LowerCasePipe
{{ value_expression | lowercase }}
CurrencyPipe
{{ value_expression | currency [ : currencyCode [ : display [ : digitsInfo [ : locale ] ] ] ]
}}
PercentPipe
{{ value_expression | percent [ : digitsInfo [ : locale ] ] }}
DAY THREE - ANGULAR ARCHITECTURE
Pipes(operatore | ) - Custom
@Pipe (decorator):definisce un nuovo Pipe agganciata a una classe
PipeTransform (interface): la classe del pipe implementa questa classe che espone un metodo
transform(value, param1,param2..paramN) di cui il primo parametro é il valore che si deve convertire, gli altri
eventuali parametri in input
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'exponential'})
export class ExponentialPipe implements PipeTransform {
transform(value: number, exponent: string): number {
let exp = parseFloat(exponent);
return Math.pow(value, isNaN(exp) ? 1 : exp);
}
}
Uso nella view
<p>
Super Hero Power: {{power | exponential: factor}}
</p>
DAY THREE - ANGULAR ARCHITECTURE
Pipes (operatore | ) - Pure e inpure
Pipe Pure:eseguite ogni volta che un cambio nel valore (primitivo o ref. dell' oggetto)
viene rilevato
Pipe Inpure: eseguite ogni volta che un cambio nel componente viene rilevato
@Pipe({
name: 'myTransformImpure',
pure: false
})
DAY THREE - ANGULAR ARCHITECTURE
Pipes (operatore | ) - Filtrare e ordinare liste
In angularjs (1.x) esistevano le pipe filter e orderBy, sono state omesse per problemi
di performance e minificazione
Si raccomanda di spostare la logica di filtering/ordering dentro il componente
DAY THREE - ANGULAR ARCHITECTURE
Angular CLI
E' uno strumento a riga di comando eseguibile che va installato tramite npm (-g
flag per utilizzo a livello globale)
Permette di generare struttura del progetto, ng-modules (non js modules),
componenti, servizi e altro, eseguire la build per la generazione del pacchetto di
distribuzione, eseguire i test e lanciare l' app.
DAY THREE - ANGULAR ARCHITECTURE
Angular CLI - Principali features
Comando Descrizione
ng new Creazione di progetto
ng generate Generazione modules, components, routes, services & pipes
ng serve Lancio dell'applicazione
ng build Build e creazione distribuzione
ng test Avvio test unitari
ng e2e Avvio test e2e
ng lint Usa un linter (controllo di errori) sul codice
DAY THREE - TUTORIAL
Tutorial
TOUR OF HEROES -
PART 1
ANGULAR CLI
DAY THREE - ANGULAR ARCHITECTURE
Change detection
La Change Detection é una caratteristica fondamentale di Angular, consiste nel
rilevare i cambiamenti nel modello e nella vista, sincronizzarli autonomamente e
notificare i listener registrati
Cosa causa i cambiamenti?
- Eventi (click del pulsante, submit di form, selezione di una option da combo)
- Chiamate Remote (fetch di dati su server)
- Timers (timeouts & intervals)
in generale, qualsiasi operazione asincrona
DAY THREE - ANGULAR ARCHITECTURE
Components
I Component sono i building block che controllano porzioni di schermo
Si implementano su due entitá distinte (component-class e component-view)
Una component-view puó contenere altri child components
Nella definizione della component-class si specifica il tag html che permette ad
angular di includere il component
DAY THREE - ANGULAR ARCHITECTURE
Component declaration & Change detection in action
Component class (hero.component.ts)
@Component({
selector: 'app-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
text = 'Some text to change';
constructor() {}
changeText() {
this.text = 'Another longer longer text to change';
}
}
View template (hero.component.html)
<div>
<label>My text is {{text}}</label>
<button (click)="changeText()">Change</button>
</div>
DAY THREE - ANGULAR ARCHITECTURE
Component in depth - @Input
Struttura parent-child component
parent-view
<app-child [childMessage]="'myMessage'"></app-child>
child-component
export class ChildComponent {
@Input() childMessage: string;
constructor() {
}
}
DAY THREE - ANGULAR ARCHITECTURE
Component in depth - @Output
parent-view
<app-child (messageEvent)="receiveMessage($event)"></app-child>
parent-component
export class ParentComponent {
constructor() { }
receiveMessage($event) {
this.message = $event
}
}
child-component
export class ChildComponent {
@Output() messageEvent = new EventEmitter<string>();
message = "Hello"
constructor() {
}
sendMessage() {
this.messageEvent.emit(this.message)
}
}
DAY THREE - ANGULAR ARCHITECTURE
Component in depth - LifeCycle Hooks
Angular gestisce tutto il ciclo di vita di un componente (create, init, change detection,
destroy).
Ogni componente puó definire delle funzioni richiamate da angular durante le varie fasi.
Le piú importanti sono
ngOnChanges(SimpleChanges) - richiamata ogni qualvolta uno o piú @input cambiano di valore
ngOnInit() - richiamata una sola volta dopo ngOnChanges
ngDoCheck() - richiamata ad ogni change detection (N.B. molto pericolosa se non la si usa bene)
ngOnDestroy() - richiamata prima che angular distrugga il component (utile per rilasciare risorse ed
evitare memory leaks)
DAY FOUR - ANGULAR FUNDAMENTALS
Forms and Validation
Angular gestisce gli elementi dei form (input, select, checkbox...) usando il
databinding two-way per sincronizzare il model con la view
<input [(ngModel)]="hero.name" placeholder="name"/>
Se occorre essere notificati, ad esempio ad ogni carattere digitato sulla input, si
aggancia un event-binding con una funzione
<input (keyup)="onKey($event)"> //onKey is a function of the component
N.B: Gli event binding possono passare degli oggetti particolari, gli $event, che
contengono anche l' elemento HTML che scatena l' evento, in questo caso un InputEvent
DAY FOUR - ANGULAR FUNDAMENTALS
Forms and Validation
É possibile sfruttare le direttive per il binding di dati
<select [(ngModel)]="hero.power" name="power">
<option *ngFor="let pow of hero.powers" [value]="pow">{{pow}}</option>
</select>
verrá renderizzata una option per ogni power (array) dell' hero
DAY FOUR - ANGULAR FUNDAMENTALS
Forms and Validation
import {FormsModule} from '@angular/forms';
Per attivare le funzionalitá built-in dei Forms, dichiarare nel modulo (solitamente nel root
module)
@NgModule({
imports: [
FormsModule,
...
]
})
DAY FOUR - ANGULAR FUNDAMENTALS
Forms and Validation
Classi css applicate all' elemento in base al suo stato nel form
DAY FOUR - ANGULAR FUNDAMENTALS
Forms and Validation
Dichiarazione di una variabile (nella view)
<input name="name" required [(ngModel)]="hero.name" #name="ngModel" >
Utilizzo dei validator (required é anche una direttiva ng!!!)
<div class="error" *ngIf="name.invalid && (name.dirty || name.touched) &&
name.errors.required">
Name is required.
</div>
N.B.: errors contiene un oggetto con tutti i tipi di errore rilevati per quell' elemento
DAY FOUR - ANGULAR FUNDAMENTALS
Forms and Validation - Reactive
import {ReactiveFormsModule} from '@angular/forms';
Per attivare le funzionalitá built-in dei Forms, dichiarare nel modulo (solitamente nel root
module)
@NgModule({
imports: [
ReactiveFormsModule,
...
]
})
DAY FOUR - ANGULAR FUNDAMENTALS
Forms and Validation - Reactive
Reactive Forms é una variante alla gestione dei Forms classica.
In questa formula la variabile del form denominata "name" é dichiarata nel component
name = new FormControl(this.hero.name);
sulla view
<input type="text" [formControl]="name">
Come form:
heroForm = new FormGroup({
'name': new FormControl(this.hero.name, [Validators.required])
})
DAY FOUR - ANGULAR FUNDAMENTALS
Forms and Validation - Reactive
I Custom Validators sono funzioni che accettano un AbstractControl in input
myValidator: {[key: string]: any} = (control: AbstractControl) => {
let wrongValue = wrongRegExp.test(control.value);
return wrongValue ? {'wrongMessageKey': {value: control.value}} : null;
}
(aderiscono all' interfaccia ValidatorFn)
dopodiché aggiungerlo
heroForm = new FormGroup({
'name': new FormControl(this.hero.name, [Validators.required])
})
N.B. Si possono creare anche attribute direttive nel caso si opti per un approccio "view" (vedere
tutorial angular)
DAY FOUR - ANGULAR FUNDAMENTALS
Forms and Validation - Dynamic
Dynamic forms é una strategia di creazione (dinamica) dei Form.
i singoli campi (form controls) si descrivono tramite oggetti.
export class DropdownControl extends BaseControl { //definire BaseControl come superclasse di tutti i controlli
controlType = 'dropdown';
options: {key: string, value: string}[] = [];
}
nella view (ciclando i form controls)
<div [ngSwitch]="control.controlType">
<select [id]="control.key" *ngSwitchCase="'dropdown'" [formControlName]="control.key">
<option *ngFor="let opt of control.options" [value]="opt.key">{{opt.value}}</option>
</select>
...other switch case
</div>
DAY FOUR - TUTORIAL
Tutorial
TOUR OF HEROES -
PART 2
COMPONENTS
DAY FOUR - ANGULAR ARCHITECTURE
Directives
Component
<app-messages></app-messages>
Structural directive (manipolano gli elementi html, es: aggiungono o
rimuovono nodi dal DOM)
<li *ngFor="let hero of heroes">
Attribute directive
<li [ngStyle]="{'font-size.px':24}"></li>
DAY FOUR - ANGULAR ARCHITECTURE
Attribute Directives
Non hanno bisogno di dichiarare template
Cambiano l' aspetto dell' elemento a cui sono agganciate
@Directive decorator (https://angular.io/api/core/Directive)
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
Uso nella view
DAY FOUR - ANGULAR ARCHITECTURE
Structural Directives - Main Built-in features
ngFor : interpreta una espressione di angular ciclando gli elementi di un array in input.
<li *ngFor="let hero of heroes">{{hero.name}}</li>
il risultato sará una transclude di tanti elementi <li> quanti sono i valori nell' array heroes e
contenenti ognuna il nome dell' hero relativo.
altre Features:
index: variabile predefinita che rappresenta l'indice dell'array che si sta ciclando
tracker: ngFor non permette oggetti duplicati, il tracker serve a definire eventualmente una
variabile (ad es. id dell'oggetto o index) che faccia da identificativo della riga renderizzata
<div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy:trackById">
({{i}}) {{hero.name}}
</div>
DAY FOUR - ANGULAR ARCHITECTURE
Structural Directives - Main Built-in features
ngIf : interpreta una espressione di angular all'interno del valore dell' attributo con cui é
dichiarato (conditional statement if)
<div *ngIf="hero.superpower === 'X-Ray Vision'">
<p class="">{{hero.name}} can see through solid objects </p>
</div>
ngSwitch: unito a ngSwitchCase determina quale dei blocchi che soddisfano la condizione
della expression debba essere renderizzata (conditional statement switch)
<div [ngSwitch]="person.gender">
<div *ngSwitchCase="'male'">Male</div>
<div *ngSwitchCase="'female'">Female</div>
<div *ngSwitchDefault>Unknown</app-unknown-hero>
DAY FOUR - TUTORIAL
Tutorial
TOUR OF HEROES -
PART 3
DISPLAY DATA
DAY FOUR - ANGULAR ARCHITECTURE
Services
I services svolgono compiti specifici con uno scopo molto ristretto (single
responsability), ad esempio occuparsi delle notifiche all' utente, loggare
messaggi, effettuare chiamate al server per un determinato ambito
Il metadata @Injectable({ providedIn: 'root' }) permette di evitare la definizione del
servizio su ogni modulo che necessita di usarlo
@Injectable({ providedIn: 'root' })
export class Logger {
log(msg: any) { console.log(msg); }
error(msg: any) { console.error(msg); }
warn(msg: any) { console.warn(msg); }
}
DAY FOUR - ANGULAR FUNDAMENTALS
Dependency injection - Providers
Un DI Provider configura un' istanza di servizio iniettabile nei componenti fornendo un contesto di propagazione
(component tree). É dichiarato:
In un metadato sulla definizione di modulo
providers : [Logger]
oppure
providers : [{ provide: Logger, useClass: BetterLogger }]
nel primo caso dichiaro l' implementazione diretta della classe, nel secondo una diversa classe che estende la
classe Logger
In un metadato (aka decoration) sulla definizione di un servizio
@Injectable({
// we declare that this service should be created
// by any injector that includes HeroModule.
providedIn: HeroModule
})
DAY FOUR - ANGULAR FUNDAMENTALS
Dependency injection - Hierarchy
Il Root Injector fornisce la
stessa istanza di servizio
(singleton) a tutti i
componenti.
NB: Nella stragrande
maggioranza dei casi é
sufficiente configurare i servizi
in singleton sul root Injector
DAY FOUR - ANGULAR FUNDAMENTALS
Dependency injection - Contesto Globale o Locale?
Il decoratore @Injectable nel seguente caso configura il servizio per essere usato solo nel modulo (e i
relativi componenti) HeroModule,
import { Injectable } from '@angular/core';
import { HeroModule } from './hero.module';
import { HEROES } from './mock-heroes';
@Injectable({
// we declare that this service should be created
// by any injector that includes HeroModule.
providedIn: HeroModule,
})
export class HeroService {
getHeroes() { return HEROES; }
DAY FOUR - ANGULAR FUNDAMENTALS
Observables
powered by RxJs
Gli Observables rendono piú facile la gestione di operazioni asincrone (come ad
esempio le fetch di dati da server) attraverso un sistema di Publisher/Subscriber
Pattern Observer: un oggetto subject contiene una lista di oggetti observers e li
notifica automaticamente ad ogni cambio di stato
Sono l'evoluzione delle Promises (in Angular si usano al posto di queste ultime,
importando la relativa libreria)
DAY FOUR - ANGULAR FUNDAMENTALS
Observables
Un Observer si sottoscrive (subscribe) a un Observable per essere notificato di uno
state change
Subcribe: la subscribe accetta un oggetto Observer che contiene con tre metodi or
da 1 a 3 funzioni in input
1. next(output) funzione richiamata dal subscriber ogni volta che uno stato é
variato
2. error: funzione richiamata dal subscriber in caso di errore
3. complete: funzione richiamata dal subscriber quando si chiuderanno le
next (eventualmente per richiamare unsubscribe())
DAY FOUR - ANGULAR FUNDAMENTALS
Observables
Esempio di utilizzo su un service (hero.service.ts) che esegue il fetch di dati su server
getHeroes (): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl);
}
Esempio di utilizzo lato componente (hero.component.ts):
ngOnInit() {
this.heroService.getHeroes().subscribe(heroes => this.heroes = heroes);
}
DAY FOUR - TUTORIAL
Tutorial
TOUR OF HEROES -
PART 4 SERVICES
DAY FIVE - ANGULAR FUNDAMENTALS
Routing, Navigation and Parameters
Il Router integrato di Angular permette di navigare l' applicazione da una vista all' altra
DAY FIVE - ANGULAR FUNDAMENTALS
Routing, Navigation and Parameters
The Routes Object
export declare type Routes = Route[];
The Route Object
{path: 'dashboard', component: DashboardComponent}
DAY FIVE - ANGULAR FUNDAMENTALS
Routing, Navigation and Parameters
import {RouterModule, Routes} from '@angular/router';
Dichiarare nel modulo (root module o module separato)
const routes: Routes = [
{path: '', redirectTo: '/dashboard', pathMatch: 'full'},
{path: 'dashboard', component: DashboardComponent},
{path: 'list', component: ListComponent},
{path: 'detail/:id', component: DetailComponent},
];
@NgModule({
imports: [
RouterModule.forRoot(routes),
...
]
})
DAY FIVE - ANGULAR FUNDAMENTALS
Routing, Navigation and Parameters
The Router Outlet Component
//dichiarato su app.component.html (in una configurazione di base)
<router-outlet></router-outlet>
Inserendo questo componente nella view del componente
root, quando il browser naviga su una determinata pagina, verrá
attivato il relativo componente
DAY FIVE - ANGULAR FUNDAMENTALS
Routing, Navigation and Parameters - Links
Abbiamo analizzato la configurazione, ma come si definiscono i link per attivare un
componente successivo?
<a routerLink="/list" >Vai alla lista</a>
La direttiva routerLink assume il controllo della url, trasforma il path all' interno dell'
attributo
Perché non usare l' attributo href sull' anchor invece? Perché questa direttiva é
dedicata ad angular e agisce nel suo contesto, trasformando i parametri ad esempio
DAY FIVE - ANGULAR FUNDAMENTALS
Routing, Navigation and Parameters - Links
La direttiva routerLinkActive, in congiunzione a routerLink permette di definire classi
css nel caso in cui la url del browser corrisponda a quella definita sull' anchor
<a routerLink="/list" routerLinkActive="classForAcrive">Vai alla lista</a>
DAY FIVE - ANGULAR FUNDAMENTALS
Routing, Navigation and Parameters - Passaggio
Parametri
{path: 'detail/:id', component: DetailComponent}
É sufficiente impostare nella view il link come espressione one-way binding
<li *ngFor="let hero of heroes">
<a routerLink="/detail/{{hero.id}}">
</li>
Il componente attivato puó reperire i parametri attraverso l' oggetto
ActivatedRoute iniettabile nel costruttore
DAY FIVE - ANGULAR FUNDAMENTALS
Routing, Navigation and Parameters - Passaggio Parametri
Oggetto Activated Route: contiene info sulla route attualmente attiva, come la url, la configurazione e
i parametri (path params & queryString) passati in input
definizione in un componente:
export class DetailComponent implements OnInit {
detailObject: DetailObject;
constructor(
private route: ActivatedRoute,
private detailService: DetailService) {}
ngOnInit(): void {
const id = +this.route.snapshot.paramMap.get('id');
this.detailService.getDetail(id)
.subscribe(detail => this.detailObject = detail);
}
}
DAY FIVE - ANGULAR FUNDAMENTALS
Routing, Navigation and Parameters - Nested Routes
DAY FIVE - ANGULAR FUNDAMENTALS
Routing, Navigation and Parameters - Nested Routes
Quando definiamo una Route, aggiungiamo una proprietá children
{ path: 'list', component: ListComponent,
children: [
{ path: 'detail/:id', component: DetailComponent }
]
}
É ora sufficiente aggiungere un <router-outlet> all' interno della view di ListComponent per
cambiare il path su browser e visualizzare la sotto-view
<li *ngFor="let hero of heroes">
<a routerLink="/detail/{{hero.id}}">
</li>
<router-outlet></router-outlet>
DAY FIVE - TUTORIAL
Tutorial
TOUR OF HEROES -
PART 5
ROUTING
DAY FIVE - ANGULAR FUNDAMENTALS
Client HTTP
import {HttpClientModule} from '@angular/common/http';
Dichiarazione per l' utilizzo del modulo (nella root solitamente)
@NgModule({
imports: [
HttpClientModule,
...
]
})
DAY FIVE - ANGULAR FUNDAMENTALS
Client HTTP
Oggetto HttpClient: permette di invocare una url remota con il supporto REST, i metodi:
request(...params) all' interno dei parametri (posizionali o a oggetto) é possibile
configurare req. method (get, post, put delete), url e varie altre opzioni
get(...params) come la request, ma il req. method preimpostato (GET)
post(...params) come la request, ma il req. method preimpostato (POST)
put(...vari params) come la request, ma il req. method é preimpostato(PUT)
delete(...vari params) come la request, ma il req. method é preimpostato(DELETE)
Tutti i metodi ritornano un Observable, di seguito trattato
DAY FIVE - ANGULAR FUNDAMENTALS
Client HTTP
Injection in un service
export class HeroService {
// si puó omettere la dichiarazione della variabile nel service, http
// diventa proprietá di HeroService e utilizzabile nei suoi metodi
constructor(
private http: HttpClient) {}
DAY FIVE - TUTORIAL
Tutorial
TOUR OF HEROES -
PART 6
HTTP
DAY FIVE - ANGULAR FUNDAMENTALS
Unit Testing
Predisposizione del Test durante la generazione del componente/servizio con
angular-cli
Jasmine Framework : lo strumento che mette a disposizione infrastruttura e utility
per facilitare la scrittura di test
<myComponent>.spec.ts : i file spec contengono i testcase di un componente
ng test: shell command per eseguire i test
test.ts: contiene la conf e le opzioni per il run dei test con jasmine, di default carica
i file *.spec.ts
DAY FIVE - ANGULAR FUNDAMENTALS
Unit Testing - Testare una unitá
Set-up dell' environment di esecuzione (beforeEach)
Creazione di una istanza del component/service da testare
Creazione del prerequisito per testare il component/service
Invocazione del metodo soggetto del test
Controllo degli expected behaviours conseguenti all' invocazione
DAY FIVE - ANGULAR FUNDAMENTALS
Unit Testing - Esempi
Esempio di test basico su componente
//component
export class LightswitchComponent {
isOn = false;
clicked() { this.isOn = !this.isOn; }
}
//component.spec.ts
describe('LightswitchComponent', () => {
it('should toggle #isOn when #clicked()', () => {
const comp = new LightswitchComponent();
expect(comp.isOn).toBe(false, 'off at first');
comp.clicked();
DAY FIVE - ANGULAR FUNDAMENTALS
Esempio di test basico su componente
//component
export class LightswitchComponent {
isOn = false;
clicked() {
this.isOn = !this.isOn;
}
}
Unit Testing - Esempi
DAY FIVE - ANGULAR FUNDAMENTALS
//component.spec.ts
describe('LightswitchComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [LightswitchComponent]
}).compileComponents();
}));
it('should toggle #isOn when #clicked()', () => {
const fixture = TestBed.createComponent(LightswitchComponent);
const app = fixture.debugElement.componentInstance;
expect(comp.isOn).toBe(false, 'off at first');
comp.clicked();
Unit Testing - Esempi
DAY FIVE - ANGULAR FUNDAMENTALS
E2E (End-to-End) Testing
banco di prova del codice in un ambiente con browser integrato e interazione con gli elementi
HTML (input, buttons ecc ecc..).
Il test non conosce la dinamica di funzionamento di componenti e servizi, solo come
usare l' interfaccia e i risultati delle operazioni in essa.
Protractor framework: lo strumento che mette a disposizione infrastruttura e utility per
facilitare la scrittura di test
<page>.e2e-spec.ts : i file e2e-spec contengono i testcase di una pagina da testare
ng e2e: shell command per eseguire i test e2e
protractor.conf.js & tsconfig.e2e.ts: contengono la conf e le opzioni per il run dei test con
protractor
DAY FIVE - ANGULAR FUNDAMENTALS
E2E (End-to-End) Testing - Page Object Pattern
Un Page Object (PO) é una classe che descrive l' interfaccia grafica di una pagina
i suoi metodi ritornano generalmente elementi presenti nella pagina
import { browser, by, element } from 'protractor';
export class HomePage {
navigateTo() {
return browser.get('/');
}
getPageTitle() {
return element(by.css('app-home h1.title')).getText();
}
}
le classi PO hanno convenzionalmente nome con suffisso po.ts
DAY FIVE - ANGULAR FUNDAMENTALS
E2E (End-to-End) Testing - Testare una pagina
Navigazione sulla pagina da testare (beforeEach)
Interazione con gli elementi visibili in pagina (fill dati form, click pulsanti)
Controllo degli expected values conseguenti (check su etichette, reindirizzamento
pagina, messaggi di avvenuta esecuzione, liste aggiornate)
DAY FIVE - ANGULAR FUNDAMENTALS
E2E (End-to-End) Testing - Testare una pagina
Usando la classe PO HomePage si costuisce il test come segue
import { HomePage } from './home.po';
describe('workspace-project Home', () => {
let page: HomePage;
beforeEach(() => {
page = new HomePage();
page.navigateTo(); //navigazione e stato iniziale di pagina
});
it('should display the title of homepage', () => {
expect(page.getPageTitle()).toEqual('Welcome to homepage!');
});
});
DAY FIVE - ANGULAR FUNDAMENTALS
E2E (End-to-End) Testing - Testare una pagina
Esempio di test su cambio di pagina
it('Should redirect to the album page when album is clicked', () => {
const album = homePage.getAlbumButton();
album.click();
expect(browser.driver.getCurrentUrl()).toContain('/album');
});
DAY FIVE - ANGULAR REFERENCES
Best Practices and Tutorials
Letture:
1. Javascript: The Good Parts
http://shop.oreilly.com/product/9780596517748.do
Sito ufficiale angular: http://angular.io
Organizzazione Progetto: https://medium.com/@michelestieven/organizing-angular-
applications-f0510761d65a

More Related Content

What's hot

Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Aaron Gustafson
 
Gitlab Training with GIT and SourceTree
Gitlab Training with GIT and SourceTreeGitlab Training with GIT and SourceTree
Gitlab Training with GIT and SourceTreeTeerapat Khunpech
 
Understanding react hooks
Understanding react hooksUnderstanding react hooks
Understanding react hooksSamundra khatri
 
Introduzione ad ECMAScript 6 (ES6) e TypeScript
Introduzione ad ECMAScript 6 (ES6) e TypeScriptIntroduzione ad ECMAScript 6 (ES6) e TypeScript
Introduzione ad ECMAScript 6 (ES6) e TypeScriptGiovanni Buffa
 
TypeScript Best Practices
TypeScript Best PracticesTypeScript Best Practices
TypeScript Best Practicesfelixbillon
 
Git 101: Git and GitHub for Beginners
Git 101: Git and GitHub for Beginners Git 101: Git and GitHub for Beginners
Git 101: Git and GitHub for Beginners HubSpot
 
Spring Framework
Spring FrameworkSpring Framework
Spring FrameworkNaLUG
 
ES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern JavascriptES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern JavascriptWojciech Dzikowski
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJSSandi Barr
 
ES6 presentation
ES6 presentationES6 presentation
ES6 presentationritika1
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.boyney123
 
The New JavaScript: ES6
The New JavaScript: ES6The New JavaScript: ES6
The New JavaScript: ES6Rob Eisenberg
 

What's hot (20)

Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]
 
Java 8 lambda
Java 8 lambdaJava 8 lambda
Java 8 lambda
 
Java collection
Java collectionJava collection
Java collection
 
Gitlab Training with GIT and SourceTree
Gitlab Training with GIT and SourceTreeGitlab Training with GIT and SourceTree
Gitlab Training with GIT and SourceTree
 
Understanding react hooks
Understanding react hooksUnderstanding react hooks
Understanding react hooks
 
Introduzione ad ECMAScript 6 (ES6) e TypeScript
Introduzione ad ECMAScript 6 (ES6) e TypeScriptIntroduzione ad ECMAScript 6 (ES6) e TypeScript
Introduzione ad ECMAScript 6 (ES6) e TypeScript
 
Git real slides
Git real slidesGit real slides
Git real slides
 
TypeScript Best Practices
TypeScript Best PracticesTypeScript Best Practices
TypeScript Best Practices
 
Git 101: Git and GitHub for Beginners
Git 101: Git and GitHub for Beginners Git 101: Git and GitHub for Beginners
Git 101: Git and GitHub for Beginners
 
GIT_In_90_Minutes
GIT_In_90_MinutesGIT_In_90_Minutes
GIT_In_90_Minutes
 
Spring Framework
Spring FrameworkSpring Framework
Spring Framework
 
TypeScript Overview
TypeScript OverviewTypeScript Overview
TypeScript Overview
 
ES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern JavascriptES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern Javascript
 
Introduction to Maven
Introduction to MavenIntroduction to Maven
Introduction to Maven
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJS
 
Github in Action
Github in ActionGithub in Action
Github in Action
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
ES6 presentation
ES6 presentationES6 presentation
ES6 presentation
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.
 
The New JavaScript: ES6
The New JavaScript: ES6The New JavaScript: ES6
The New JavaScript: ES6
 

Similar to Corso js and angular

Acadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewAcadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewFrancesco Sciuti
 
What is new in C# 2018
What is new in C# 2018What is new in C# 2018
What is new in C# 2018Marco Parenzan
 
Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)STELITANO
 
Javascript - 7 | WebMaster & WebDesigner
Javascript - 7 | WebMaster & WebDesignerJavascript - 7 | WebMaster & WebDesigner
Javascript - 7 | WebMaster & WebDesignerMatteo Magni
 
LINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsLINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsJUG Genova
 
Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)
Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)
Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)From The Front
 
Introduzione a JavaScript
Introduzione a JavaScriptIntroduzione a JavaScript
Introduzione a JavaScriptGiovanni Buffa
 
Love Your Database (ESC 2k16)
Love Your Database (ESC 2k16)Love Your Database (ESC 2k16)
Love Your Database (ESC 2k16)PgTraining
 
What's Big Data? - Big Data Tech - 2015 - Firenze
What's Big Data? - Big Data Tech - 2015 - FirenzeWhat's Big Data? - Big Data Tech - 2015 - Firenze
What's Big Data? - Big Data Tech - 2015 - FirenzeAlberto Paro
 
Introduzione a scala prima parte
Introduzione a scala   prima parteIntroduzione a scala   prima parte
Introduzione a scala prima parteOnofrio Panzarino
 

Similar to Corso js and angular (20)

Acadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewAcadevmy - TypeScript Overview
Acadevmy - TypeScript Overview
 
Javascript
JavascriptJavascript
Javascript
 
Riepilogo Java C/C++
Riepilogo Java C/C++Riepilogo Java C/C++
Riepilogo Java C/C++
 
What's new in C# 7
What's new in C# 7What's new in C# 7
What's new in C# 7
 
What is new in C# 2018
What is new in C# 2018What is new in C# 2018
What is new in C# 2018
 
R Vectors
R VectorsR Vectors
R Vectors
 
8 Algoritmi
8   Algoritmi8   Algoritmi
8 Algoritmi
 
Array
ArrayArray
Array
 
Java lezione 7
Java lezione 7Java lezione 7
Java lezione 7
 
Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)
 
Javascript - 7 | WebMaster & WebDesigner
Javascript - 7 | WebMaster & WebDesignerJavascript - 7 | WebMaster & WebDesigner
Javascript - 7 | WebMaster & WebDesigner
 
LINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsLINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMs
 
Office & VBA - Giorno 6
Office & VBA - Giorno 6Office & VBA - Giorno 6
Office & VBA - Giorno 6
 
Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)
Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)
Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)
 
Introduzione a JavaScript
Introduzione a JavaScriptIntroduzione a JavaScript
Introduzione a JavaScript
 
CleanCode
CleanCodeCleanCode
CleanCode
 
Love Your Database (ESC 2k16)
Love Your Database (ESC 2k16)Love Your Database (ESC 2k16)
Love Your Database (ESC 2k16)
 
What's Big Data? - Big Data Tech - 2015 - Firenze
What's Big Data? - Big Data Tech - 2015 - FirenzeWhat's Big Data? - Big Data Tech - 2015 - Firenze
What's Big Data? - Big Data Tech - 2015 - Firenze
 
Introduzione a scala prima parte
Introduzione a scala   prima parteIntroduzione a scala   prima parte
Introduzione a scala prima parte
 
Sql 3
Sql 3Sql 3
Sql 3
 

Recently uploaded

Esperimenti_laboratorio di fisica per la scuola superiore
Esperimenti_laboratorio di fisica per la scuola superioreEsperimenti_laboratorio di fisica per la scuola superiore
Esperimenti_laboratorio di fisica per la scuola superiorevaleriodinoia35
 
CON OCCHI DIVERSI - catechesi per candidati alla Cresima
CON OCCHI DIVERSI - catechesi per candidati alla CresimaCON OCCHI DIVERSI - catechesi per candidati alla Cresima
CON OCCHI DIVERSI - catechesi per candidati alla CresimaRafael Figueredo
 
Corso di digitalizzazione e reti per segretario amministrativo
Corso di digitalizzazione e reti per segretario amministrativoCorso di digitalizzazione e reti per segretario amministrativo
Corso di digitalizzazione e reti per segretario amministrativovaleriodinoia35
 
IL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla Cresima
IL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla CresimaIL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla Cresima
IL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla CresimaRafael Figueredo
 
San Giorgio e la leggenda del drago.pptx
San Giorgio e la leggenda del drago.pptxSan Giorgio e la leggenda del drago.pptx
San Giorgio e la leggenda del drago.pptxMartin M Flynn
 
RICERCA_SUGLI ANFIBI PER LA PRIMA MEDIA.
RICERCA_SUGLI ANFIBI PER LA PRIMA MEDIA.RICERCA_SUGLI ANFIBI PER LA PRIMA MEDIA.
RICERCA_SUGLI ANFIBI PER LA PRIMA MEDIA.giuliofiorerm
 
lezione di fisica_I moti nel piano_Amaldi
lezione di fisica_I moti nel piano_Amaldilezione di fisica_I moti nel piano_Amaldi
lezione di fisica_I moti nel piano_Amaldivaleriodinoia35
 
XIII Lezione - Arabo G.Rammo @ Libera Accademia Romana
XIII Lezione - Arabo G.Rammo @ Libera Accademia RomanaXIII Lezione - Arabo G.Rammo @ Libera Accademia Romana
XIII Lezione - Arabo G.Rammo @ Libera Accademia RomanaStefano Lariccia
 
XI Lezione - Arabo LAR Giath Rammo @ Libera Accademia Romana
XI Lezione - Arabo LAR Giath Rammo @ Libera Accademia RomanaXI Lezione - Arabo LAR Giath Rammo @ Libera Accademia Romana
XI Lezione - Arabo LAR Giath Rammo @ Libera Accademia RomanaStefano Lariccia
 

Recently uploaded (9)

Esperimenti_laboratorio di fisica per la scuola superiore
Esperimenti_laboratorio di fisica per la scuola superioreEsperimenti_laboratorio di fisica per la scuola superiore
Esperimenti_laboratorio di fisica per la scuola superiore
 
CON OCCHI DIVERSI - catechesi per candidati alla Cresima
CON OCCHI DIVERSI - catechesi per candidati alla CresimaCON OCCHI DIVERSI - catechesi per candidati alla Cresima
CON OCCHI DIVERSI - catechesi per candidati alla Cresima
 
Corso di digitalizzazione e reti per segretario amministrativo
Corso di digitalizzazione e reti per segretario amministrativoCorso di digitalizzazione e reti per segretario amministrativo
Corso di digitalizzazione e reti per segretario amministrativo
 
IL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla Cresima
IL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla CresimaIL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla Cresima
IL CHIAMATO ALLA CONVERSIONE - catechesi per candidati alla Cresima
 
San Giorgio e la leggenda del drago.pptx
San Giorgio e la leggenda del drago.pptxSan Giorgio e la leggenda del drago.pptx
San Giorgio e la leggenda del drago.pptx
 
RICERCA_SUGLI ANFIBI PER LA PRIMA MEDIA.
RICERCA_SUGLI ANFIBI PER LA PRIMA MEDIA.RICERCA_SUGLI ANFIBI PER LA PRIMA MEDIA.
RICERCA_SUGLI ANFIBI PER LA PRIMA MEDIA.
 
lezione di fisica_I moti nel piano_Amaldi
lezione di fisica_I moti nel piano_Amaldilezione di fisica_I moti nel piano_Amaldi
lezione di fisica_I moti nel piano_Amaldi
 
XIII Lezione - Arabo G.Rammo @ Libera Accademia Romana
XIII Lezione - Arabo G.Rammo @ Libera Accademia RomanaXIII Lezione - Arabo G.Rammo @ Libera Accademia Romana
XIII Lezione - Arabo G.Rammo @ Libera Accademia Romana
 
XI Lezione - Arabo LAR Giath Rammo @ Libera Accademia Romana
XI Lezione - Arabo LAR Giath Rammo @ Libera Accademia RomanaXI Lezione - Arabo LAR Giath Rammo @ Libera Accademia Romana
XI Lezione - Arabo LAR Giath Rammo @ Libera Accademia Romana
 

Corso js and angular

  • 1. CORSO JAVASCRIPT Basic introduction of Vanilla JS and Angular
  • 2. DAY ONE - JAVASCRIPT HISTORY JS é stato creato nel 1995 da Brendan Eich, un programmatore della Netscape. Principalmente per sopperire all' assenza di un linguaggio che potesse interagire con i browser e permettere di automatizzare i processi. Successivamente In parallelo vennero sviluppati altri tentativi sullo stesso piano come JScript e (dopo) ActionScript della Macromedia (di cui fece parte anche Einch) fino alla nascita della specifica di Jesse James Garrett che rivoluzionó JS definendo un set di tecnologie che facessero da spina dorsale per le future implementazioni del linguaggio e portó all' avvento di AJAX . Da quel punto in poi la community é stata molto attiva producendo migliaia di librerie tra cui Jquery, Prototype e Dojo. Si istituirono altre fondazioni open source che avevano come obiettivo quello di sviluppare una libreria standard per lo sviluppo su javascript fuori dal contesto del browser da cui nacque Node.js
  • 3. DAY ONE - JAVASCRIPT HISTORY 1995: At Netscape, programmer Brendan Eich created "JavaScript". 1996: Microsoft releases "JScript", a port for IE3. 1997: JavaScript was standardized in the "ECMAScript" spec. 2005: "AJAX" was coined and the web 2.0 age begins. 2006: jQuery 1.0 was released. 2010: Node.JS was released. 2015: ECMAScript 6 was released.
  • 4. DAY ONE - VARIABILI Variabili Le variabili sono "contenitori di dati" generici (non tipizzati) Dichiarazione: var, let or const (since ES6) Scope: Global, Local (aka Function Scope) Data Types Variabili implicite: this, arguments [window e console (solo su client)]
  • 5. DAY ONE - VARIABILI Tipi di dati null var x = null; undefined var x; Number var x = 1; var y = new Number(1); Boolean var x = false; var y = new Boolean(expression) String var x = "John"; var y = new String("Jack"); Date var x = new Date(2018, 1, 1, 10, 33, 30); var y = new Date(milliseconds) Array var x = ["el1", "el2"]; var y = new Array(); Object var x = {firstName: "John", lastName: "Doe"}; var y= new Boolean(); Regexp var x = /ab+c/; var y = new RegExp("ab+c"); Function var x = function(a, b) {return a+b;} var y = new Function("a", "b", "return a+b;"); Symbol var x = Symbol();
  • 6. DAY ONE - VARIABILI Hoisting: Declare Your Variables on top “Thanks to the Hoisting a variable can be used before it has been declared. (except let and const variables)” x = 5; //assignment doSomethingWithX(x); //using variable before initialization var x; //declaration Lo stesso vale per le funzioni
  • 7. DAY ONE - VARIABILI One statement, many variables var a, b, c=1; // a e b sono undefined, c é uguale a 1 var a=b=c=1; // a, b e c valgono 1; Ridichiarazione var a = 1; var a; console.log(a); // a vale ancora 1; Migrazione da var (old ES versions) a let/const var a = 1; // vecchia sintassi let a = 1; // variabili che possono mutare il valore dopo la dichiarazione const a = 1; // variabili che non possono mutare il proprio valore dopo la dichiarazione
  • 8. DAY ONE - VARIABILI Type Coercion “Type coercion is the process of converting value from one type to another (such as string to number, object to boolean, and so on). Any type, be it primitive or an object, is a valid subject for type coercion. To recall, primitives are: number, string, boolean, null, undefined + Symbol (added in ES6).”
  • 9. DAY ONE - VARIABILI Type Coercion true + false ====> 1 true + true ====> 2 12 / "6" ====> NaN "number" + 15 + 3 ====> "number153" 15 + 3 + "number" ====> "18number" "foo" + + "bar" ====> "fooNaN" 'true' == true ====> false false == 'false' ====> false false == '' ====> true [] + null + 1 ====> "null1" {}+[]+{}+[1] ====> "[object Object][object Object]1"
  • 10. DAY ONE - OPERATORS Gli operatori sono simboli che permettono di assegnare, comparare e modificare valori in una variabile o condizione Si suddividono in Assignment, Conditional, Logical, Bitwise Altri operatori speciali: - delete, - typeof, - instanceof - in (usato nei loop for) - void
  • 11. DAY ONE - OPERATORS Operatori Aritmetici (e non) Simbolo Descrizione = Assegnazione variabile + Addizione numerica/Concatenazione stringhe o oggetti/Unario più (tenta la conversione in numerico dell' oggetto) * Moltiplicazione / Divisione % Resto -- Assegnazione e decremento (di variabile) ++ Assegnazione e incremento (di variabile)
  • 12. DAY ONE - OPERATORS Operatori comparativi Logical operators implement lazy evaluation Gli operatori sono pressoché identici (==, !=, >, <, >=, <=, &&, ||) a quelli Java con la differenza tra strict/loose comparison 0==''; //loose comparison, returns true 0===''; //strict comparison, returns false Nonostante la strict comparison si possono commettere errori true + true === 2 //true true === 1 // false (hopefully)
  • 13. DAY ONE - OPERATORS Operatori comparativi Operatore Ternario ( condition ) ? then : else var message = age > 18 ? "Adult" : "Too young"; a differenza di Java, posso eseguire un ternario senza assegnazione age > 18 ? doThis() : doThat();
  • 14. DAY ONE - DATA TYPES Data types Le strutture di dati sono il building block per le tipologie di oggetti definibili nelle variabili Primitivi (immutabili): null, undefined, string, Boolean, number, Symbol Oggetti (referenced): Date, Array, Object, Function
  • 15. DAY ONE - DATA TYPES Numbers e Aritmetica I numeri includono particolari numeri speciali Positive infinity -> Number.POSITIVE_INFINITY Negative infinity ->Number.NEGATIVE_INFINITY NaN (not a number) Il numero massimo di decimale é 17, e l' aritmetica sui numeri a virgola mobile non é accuratissima! var x = 0.1+0.2; // x will be 0.30000000000000004, what a mess!! var x = ((0.1*10)+(0.2*10))/10; // x now will be 0.3 Don't mess with mixed data types console.log(1+2+3) --> 6 console.log("5"+2+3) --> 523 console.log(2+3+"5") --> 55
  • 16. DAY ONE - DATA TYPES Numbers e Aritmetica - Math Math é un oggetto implicito di utility per svolgere operazioni aritmetiche. Contiene fondamentali metodi e costanti per il calcolo, qualche esempio: Math.PI pigreco Math.abs(n) valore assoluto di un numero Math.pow(n, p) potenza di p di un numero n Math.min(n, n1..nx)/Math.max(n,n1..., nx) ritorna il numero maggiore/minore tra i parametri in ingresso .... e molto altro (random, round, sin, acos)
  • 17. DAY ONE - DATA TYPES Strings Le stringhe sono variabili primitive (single/double quoted), tuttavia possiedono diversi metodi e proprietá e funzioni tra cui: length ritorna la lunghezza della stringa indexOf ritorna l' indice numerico della prima occorrenza di un testo specifico all' interno di una stringa slice/substring/substr seppure con sottili differenze tutte e tre tagliano una stringa dati i due estremi posizionali replace sostituisce le occorrenze di un testo specifico (o regexp) con un altro testo toUpperCase/LowerCase il nome dice tutto Honorable mentions: charAt, trim, concat e molto altro!
  • 18. DAY ONE - DATA TYPES Objects Gli oggetti sono normalmente definiti come literals i cui valori vengono espressi come mappa chiave:valore: let car = { name: "Saturn", // a property containing a string getCar: function() {...}, // a property containing a function nestedCar: { // a property containing a nested object nestedName: "nestedValue" } } per accedere alla property nestedName si segue il path dell' oggetto car.nestedCar.nestedName oppure car["nestedCar"]["nestedName"]
  • 19. DAY ONE - DATA TYPES Objects - Metodi del costruttore Object Object, oltre ad essere istanziabile (creando un nuovo oggetto) puó essere utilizzato attraverso i metodi del costruttore (senza istanza) che contengono funzioni fondamentali nello sviluppo, di seguito i metodi piú utilizzati nello sviluppo: Object.create(obj) ritorna un nuovo oggetto dal prototipo di obj Object.keys(obj) ritorna un array contenente le property names di obj Object.assign(obj): ritorna un nuovo oggetto copiando tutte le prop di obj altri metodi sperimentali e non come Object.is, Object.freeze, Object.observe
  • 20. DAY ONE - DATA TYPES Dates Gli oggetti Date rappresentano un singolo momento nel tempo Costruzione di una istanza dell' oggetto new Date(); //date based on client system settings current time (with TZ) new Date(value); //current time in millis new Date(dateString); //try parsing a date from a string new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]); //using single fields, omitted ones are setted by default to 0 //date valide var today = new Date(); var birthday = new Date('December 17, 1995 03:24:00'); var birthday = new Date('1995-12-17T03:24:00'); var birthday = new Date(1995, 11, 17); var birthday = new Date(1995, 11, 17, 3, 24, 0);
  • 21. DAY ONE - DATA TYPES Dates - Formattazione toString: il metodo di default formatta la data in base al locale impostato sulle impostazioni del sistema del client Sun Sep 16 2018 16:00:43 GMT+0200 (Central European Summer Time) toLocaleDateString fornisce una variante con cui visualizzare una data in base al locale e la timezone console.log(event.toLocaleString('en-GB', { timeZone: 'UTC' })); 20/12/2012, 03:00:00 Non é possibile specificare un date format pattern nativamente, per questo ed altri motivi si utilizzano librerie specifiche per la manipolazione e formattazione di date (moment)
  • 22. DAY ONE - DATA TYPES Dates - Getters e setters É possible recuperare e impostare i singoli valori di una data attraverso funzioni getter & setter. getFullYear()/setFullYear(n) //anno (locale) 4 digits getMonth()/setMonth(n) 0-11 getDate()/setDate(n) //giorno del mese - 1-31 getDay()/setDay(n) //giorno della settimana -0-6 getHours()/setHours(n) //ora locale 0-23 getMinutes()/setMinutes(n) //minuti 0-59 getSeconds()/setSeconds(n) //secondi 0-59 getMilliseconds()/setMilliseconds(n) //millis 0-999 getTime()/setTime(n) //millisecondi dal 1 gennaio 1970 per la lista completa consultare https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
  • 23. DAY ONE - DATA TYPES Arrays Un array é una lista di oggetti a cui é possibile accedere tramite un indice let fruits = ["Apple", "Banana", "Orange"]; console.log(fruits[1]); // prints Banana
  • 24. DAY ONE - DATA TYPES Arrays Per aggiunta/rimozione di valori: push aggiunge uno o piú elementi in coda all'array fruits.push("Watermelon"); //fruits contains ["Apple", "Banana", "Orange", "Watermelon"] pop rimuove l'ultimo elemento dalla coda dell'array (ritorna l' elemento stesso) fruits.pop(); //fruits contains ["Apple", "Banana"] shift rimuove il primo elemento dalla testa dell' array (ritorna l' elemento stesso) fruits.shift(); //fruits contains ["Banana", "Orange"] unshift aggiunge uno o piú elementi dalla testa dell' array fruits.unshift("Watermelon"); //fruits contains ["Watermelon", "Apple", "Banana", "Orange"]
  • 25. DAY ONE - DATA TYPES Arrays per alterare il valore di un elemento esistente é sufficiente assegnarlo tramite indice fruits[1] = "Pear"; // fruits contains ["Apple", "Pear", "Orange"]; Altri metodi fondamentali: join(separator): converte l' array in una stringa con valori separati da separator fruits.join(" * ");// "Apple * Banana * Orange" splice(idx, nElem) ritorna un nuovo array rimuovendo nElem elementi iniziando da idx fruits.splice(0, 2);// ["Apple", "Banana"] NB: l' array stesso é cambiato! slice(idxStart,idxEnd) ritorna un nuovo array contenente gli elementi compresi tra idxStart e idxEnd fruits.slice(0, 2);// ["Apple", "Banana", "Orange"] NB: l' array non é cambiato!
  • 26. DAY ONE - DATA TYPES Arrays - Manipolazione massiva Le tre principali funzioni per scorrere un array sono map rimappa un array in un altra lista, i cui valori sono determianti da una funzione in ingresso a cui viene passato ogni singolo elemento let numbers = [1, 3, 6]; let pow = numbers.map(function(item) { return item*item;}); // pow conterrá le potenze dell' array iniziale filter ritorna un sottoinsieme dell' array i cui elementi soddisfino le condizioni della funzione passata in input let numbers = [1, 3, 6, 17, 22]; let filtered = numbers.filter(function(item) { return item < 10}); //filtered conterrá solo gli elementi i cui valore é piú basso di 10 reduce trasforma un array in un altro oggetto (passato in input come secondo parametro) ciclando ogni elemento let numbers = [1, 3, 6, 17, 22]; let total = numbers.reduce(function(total, item) { return total+item}, 0); //total = 49 la funzione in ingresso prende per primo parametro l' accumulatore (oggetto che di volta in volta viene ritornato), l' elemento N dell' array, l'indice dell' elemento (opzionale), l' array stesso che contiene l' elemento
  • 27. DAY ONE - DATA TYPES Regular expressions Una regular expression é un' automa per la ricerca di pattern all' interno di una stringa. let re = /world/; console.log(re.test("Hello world!!")); // returns true; console.log(re.test("Hello word")); // returns false; possono essere molto potenti e utilizzate per validazioni di campi o per estrarre particolari campi da stringhe di cui conosciamo la struttura. Esempio di regular expression di validazione di un codice fiscale: let reCf = /^(?:(?:[B-DF-HJ-NP-TV-Z]|[AEIOU])[AEIOU][AEIOUX]|[B-DF-HJ-NP-TV-Z]{2}[A-Z]){2}(?:([dLMNP-V]){1}(?:([dLMNP-V]){1}(?:[w]{1,2}|([A- EHLMPR-T](?:[04LQ][1-9MNP-V]|[1256LMRS][dLMNP-V])|[DHPS][37PT][0L]|[ACELMRT][37PT][01LM])(?:[w]{1,3}|([A-MZ][1-9MNP-V][dLMNP-V]{2}|[A- M][0L](?:[1-9MNP-V][dLMNP-V]|[0L][1-9MNP-V]))([A-Z]){0,1}){0,1}){0,1}){0,1}){0,1}$/i; var isValidCf = reCf.test("RSSMRA90R11F205H"); // returns true if it is a valid CF Il mondo delle RegExp é vasto, comprende flags, sets di caratteri, sistemi di raggruppamento e molto altro. Per saperne di piú: https://javascript.info/regular-expressions
  • 28. DAY ONE - DATA TYPES Functions Le funzioni sono blocchi di codice (routines) che eseguono particolari tasks. Una funzione viene attivata tramite chiamata (call) da parte di "qualcuno". Le funzioni sono oggetti, in quanto tali possono essere assegnate alle variabili, passate come parametro, essere un valore di ritorno di una funzione
  • 29. DAY ONE - DATA TYPES Functions Invocation Definita una funzione function doSomething(a, b) { return a*b; } possiamo usare strategie diverse di invocazione: 1 - doSomething(10, 3); 2 - doSomething.call(null, 10, 3) 3 - doSomething.apply(null, [10, 3])
  • 30. DAY ONE - DATA TYPES Functions - Call & Apply nei casi di call e apply il primo parametro della funzione é l' oggetto di contesto. La keyword this che si riferisce all' oggetto di contesto con cui é stata invocata la funzione function doSomething() { return this.firstName + " " + this.lastName; } var person = {firstName: "John", lastName: "Doe"}; doSomething.call(person); doSomething.apply(person); //in both cases return is John Doe"
  • 31. DAY ONE - DATA TYPES Functions - Types Declared function functionName(parameters) { //do something; } Anonymous (self invoking function) (function(parameters) { //do something; }());// note the parenthesis at the end and wrapping the function Function expression (a function expression is stored in a variable) var myFunction = function(parameters) { //do something; } myFunction(myParam1, myParam2, myParamX); // function call
  • 32. DAY ONE - DATA TYPES Functions - Arrow (ES6) Le funzioni a freccia é una sintassi piú compatta della definizione di una funzione Il seguente codice: var myFunction = (aString) => aString.length; é equivalente a: var myFunction = function(aString) => { return aString.length; } la compattazione del codice é evidente nella manipolazione degli array let materials =["Hydrogen","Helium", "Lithium","Beryllium"]; let materialLength = materials.map(item => item.length); // [8, 6, 7, 9]
  • 33. DAY ONE - DATA TYPES typeof & instanceof Sono due keyword per testare se una variabile contiene una certo tipo di dato Usando typeof otteniamo la rappresentazione in formato stringa del tipo di oggetto typeof 'example string' == 'string'; // true Usando instanceof si compara il Type con cui é stato dichiarato in fase di costruzione [] instanceof Array; // true Usa typeof per le variabili primitive, instanceof per gli oggetti complessi var MyClass = function () {}; var instance = new MyClass(); typeof instance; // object instance instanceof MyClass; // true
  • 34. DAY ONE - DATA TYPES ES6 Features - Notable mentions String template literals var first ="John"; var last = "Doe"; var name = `Your name is ${first} ${last}.`; Default parameters value var link = function(height = 50, color = 'red', url = 'http://loremipsum.com') { ... } Spread operator ( ... ) function myFunction(x, y, z) { } var args = [0, 1, 2]; myFunction(...args);
  • 35. DAY ONE - EXERCISES Let's try it... What is the value of the hello variable in the following expression? var hello;
  • 36. DAY ONE - EXERCISES Let's try it... What is the value of the hello variable in the following expression? var hello; ===> undefined
  • 37. DAY ONE - EXERCISES Let's try it... What does the following expression return? var x = 3 / "bob";
  • 38. DAY ONE - EXERCISES Let's try it... What does the following expression return? var x = 3 / "bob"; ===> NaN
  • 39. DAY ONE - EXERCISES Let's try it... What is the result of "80" + 71.2: A - 151.2 B - 151 C - "8071.2"
  • 40. DAY ONE - EXERCISES Let's try it... What is the result of "80" + 71.2: A - 151.2 B - 151 C - "8071.2" C - "8071.2"
  • 41. DAY ONE - EXERCISES Let's try it... What is the result of 2 +"2": A - 4 B - "4" C - "22"
  • 42. DAY ONE - EXERCISES Let's try it... What is the result of 2 +"2": A - 4 B - "4" C - "22" C - "22"
  • 43. DAY TWO - STATEMENTS Statements Gli statements eseguono istruzioni, assegnazioni, dirigono i flussi sui diversi blocchi di codice Conditional statements: if/else/else if, switch Loop statements: for, while, do..while Error handling: try/catch/finally
  • 44. DAY TWO - STATEMENTS if/else if/else Statement if é la keyword per descrivere un flusso di azioni in base a condizioni differenti if (condition) { block of code to be executed if the condition is true } else é la keyword per definire il blocco di codice da eseguire se la condizione di if é false if (condition) { block of code to be executed if the condition is true } else { block of code to be executed if the condition is false } else if é la keyword per definire una nuova condizione nel caso la if non sia stata soddisfatta if (condition) { block of code to be executed if the condition is true } else if (condition2) { block of code to be executed if the condition is false and condition2 is true }
  • 45. DAY TWO - STATEMENTS while/do while Statement while é la keyword per descrivere un flusso di azioni iterate finché la condizione non é false while (condition) { block of code to be executed till condition become false } do é la keyword, unita a while (in coda), che descrive il medesimo flusso, la differenza é che la prima iterazione viene eseguita sempre. do { i will be executed at least 1 time! block of code to be executed till condition become false } while (condition);
  • 46. DAY TWO - STATEMENTS for Statement for é la keyword per descrivere un flusso di azioni iterate un numero definito di volte: for (var i=0; i < heroes.length; i++) { console.log(heroes[i].name); //prints all heroes names from the array } for...in é una sintassi per ciclare le properties su un oggetto var hero = {name: "Batman", superpower: "Richness"}; for (x in hero) { console.log(x+"="+hero[x]); //prints all properties and values of hero object }
  • 47. DAY TWO - STATEMENTS switch Statement switch - case é la keyword per indirizzare in un blocco di codice basandosi sul valore di una variabile switch (hero.name) { case "Batman": takeBatMobile(); break; case: "Superman": useSuperSpeed(); break; default: break; } break é la keyword con cui si esce dal blocco case (evita di eseguire altri test sullo switch e ottimizza) default é la keyword all' interno dello switch per definire il blocco di codice da eseguire se nessuno dei case é soddisfatto
  • 48. DAY TWO - STATEMENTS try/catch/finally/trow Statement try/catch definisce un blocco di codice con eccezione controllata try { someRiskyFunction(); } catch(e) { console.log(e); } throw é l' istruzione che permette di rilanciare un errore throw "Error2"; // String type throw 42; // Number type throw true; // Boolean type throw {toString: function() { return "I'm an object!"; } }; finally definisce un blocco di codice che verrá eseguito indipendentemente dall' esito all' interno della try/catch try { someRiskyFunction(); } catch(e) { console.log(e); } finally { console.log("This block will be executed in any case"); }
  • 49. DAY TWO - BUILTIN FEATURES Scope Lo scope di una variabile definisce il livello di appartenenza della stessa all' interno del flusso di codice Local scope: l' accesso alla variabile é ristretto all' interno di un blocco di codice Global scope: l' accesso é garantito su tutti i blocchi di codice Una variabile definita in una funzione é accessibile da una sua sottofunzione
  • 50. DAY TWO - BUILTIN FEATURES Scope Globale var i = 5; // is accessible inside functions, but everyone can access and change it function doSomething() { return i*2; } Locale function doSomething() { var i = 5; // i is accessible only inside this function return i*2; } Nested Function function doSomething() { var i = 5; // i is accessible inside this function and its subfunction function doSomethingElse() { return i*2; } doSomethingElse(); return i; }
  • 51. DAY TWO - BUILTIN FEATURES Closure “Una closure è quello che una funzione è capace di ricordare del contesto (lexical scope) dalla quale proviene, anche se viene eseguita al di fuori di esso.” Permette di isolare il contesto di variabili
  • 52. DAY TWO - BUILTIN FEATURES Closure Per isolare una variabile, al fine di renderla accessibile solo all' interno di un contesto e mantenendo il suo stato, usiamo le Function Closure sfruttando le self invoking functions: var counterFunction = (function() { var counter = 0; return function() { return ++counter; } }()); La funzione viene invocata nel momento in cui viene definita la variabile counterFunction, in questo modo possiamo invocare counterFunction() che ritornerá il valore incrementato di counter console.log(counterFunction()); // returns 1 console.log(counterFunction()); // second time, returns 2
  • 53. DAY TWO - BUILTIN FEATURES Prototypes Un oggetto puó ereditare (o estendere) un altro oggetto (che fa da prototipo) Non é consigliabile estendere i tipi di base (js versions conflicts and many more issues!) Old ways vs New Ways (ECMAScript 2015)
  • 54. DAY TWO - BUILTIN FEATURES Prototypes - the old way Prima dell' avvento delle “classes”, per creare un oggetto: function Cat(name) { this.name = name; this.meow = function () { return this.name + " meow !"; } } var cat = new Cat("Garfield"); console.log(cat); // prints Cat { name:'Garfield'} console.log(cat.meow()); //prints "Garfield meow !" Problemi con le "new"? var cat = Cat("Garfield"); // error! this is undefined console.log(cat);
  • 55. DAY TWO - BUILTIN FEATURES Prototypes - the old way Estendere un oggetto con prototype function Animal(name) { this.name = name; } Animal.prototype.constructor = Animal; Animal.prototype.speak = function () { return "My name is " + this.name; }; function Cat(name) { Animal.call(this, name); //call super constructor Animal } Cat.prototype = new Animal(); Cat.prototype.constructor = Cat; cat = new Cat("Garfield"); console.log(cat.speak());// prints "My name is Garfield"
  • 56. DAY TWO - BUILTIN FEATURES Prototypes - the old way La proprietá __proto__ é un accessor di Object.prototype che permette di definire anch'esso il prototipo di un oggetto che si vuol creare. É una feature deprecata e comporta varie issue di performance Estendere un oggetto con __proto__ var Animal = function() { } var cat = {}; var animal = new Animal(); car.prototype.__proto__ = animal; //DO NOT USE Un modo migliore é l' utilizzo di Object.create var cat = Object.create(animal); //extends properties and methods of animal, without affecting the "animal" variable
  • 57. DAY TWO - BUILTIN FEATURES Prototypes - the new way Introdotto il concetto di “classi” Codice piú pulito e senza fraintendimenti sulla variabile this Piú object oriented
  • 58. DAY TWO - BUILTIN FEATURES Prototypes - the new way Estendere un oggetto class Animal { constructor(name) { this.name = name; } speak() { return "My name is " + this.name; } } class Cat extends Animal { constructor(name) { super(name); } } let cat = new Cat("Garfield"); cat.speak();
  • 59. DAY TWO - BUILTIN FEATURES Timeouts - postponing execution Il timeout é una funzionalitá (praticamente una function) built-in sul browser. Permette di ritardare l'esecuzione della function passata come parametro É possibile cancellare l' esecuzione (se si ha necessitá di farlo) Esempio: let myFunction = function () { console.log("Hello!"); }; var timeoutId = setTimeout(myFunction, 1000); //prints "Hello!" after 100 milliseconds //clearTimeout(intervalId); // uncomment this if you want to stop the timeout execution
  • 60. DAY TWO - BUILTIN FEATURES Interval - repeating Timeouts L' interval permette di eseguire funzioni a intervalli regolari di tempo, é di fatto un timeout ripetuto É possibile cancellare la schedulazione dell' intervallo (se si ha necessitá) Esempio: let myFunction = function () { console.log("Hello!"); }; var intervalId = setInterval(myFunction, 100); //prints "Hello!" at intervals of 100 milliseconds, forever and ever... //clearInterval(intervalId); //uncomment if you want to stop the interval, otherwise it will keep going
  • 61. DAY TWO - BUILTIN FEATURES Callbacks Una callback (o higher-order function) é un design pattern che prevede una funzione passata come parametro (argument) ad un' altra funzione ed eseguita in un determinato momento da quest' ultima; Sono soprattutto utili in caso di funzioni asincrone (il risultato non é disponibile al momento dell' uscita dalla funzione invocata), come Timeouts, Intervals o le Promises che verranno trattate piú avanti
  • 62. DAY TWO - BUILTIN FEATURES Callbacks Esempio di callback function doSomethingAndNotify(a, b, fnCB) { var computed = a + b; var options = {computedValue: computed}; setTimeout(function () { fnCB(options); }, 100); } doSomethingAndNotify(1, 2, function (options) { //this is my callback fnCB!!! console.log(options.computedValue); // prints the resulting computation, well done! });
  • 63. DAY TWO - BUILTIN FEATURES Promises Una Promise é un oggetto che rappresenta l' eventuale completamento di un task asincrono Native da ECMAScript 6 Ha un costruttore con una funzione che prende due parametri in ingresso: resolve completamento riuscito reject completamento fallito L'esito del task asincrono é gestibile attraverso due metodi: then prende in input una funzione di callback per il completamento riuscito catch prende in input una funzione di callback per il completamento fallito La funzione di callback di completamento riuscito puó ritornare un' altra promise o un oggetto, permettendo il chaining di piú Promises
  • 64. DAY TWO - BUILTIN FEATURES Promises Native Esempio di una Promise nativa let heroes = [{name: "Batman"}, {name: "Robin"}]; let findHeroesNames = function () { return new Promise((resolve, reject) => { if (heroes) resolve(heroes.map(item => item.name)); else reject(heroes); }); }; findHeroesNames().then(function (heroes) { console.log(heroes); //prints an array ["Batman", "Robin"] }).catch(function (err) { console.log("Something went wrong here: " + err); });
  • 65. DAY TWO - BUILTIN FEATURES Promises - Chaining Il Chaining permette di avere delle operazioni asincrone a catena, eseguite una dopo l' altra Esempio di una Promise chain let heroes = [{name: "Batman", superpower:"Cleverness"}, {name: "Robin", superpower: "Friend of Batman"} ]; let findHeroes = function() { return new Promise(resolve, reject) { if (heroes) resolve(heroes); else reject(heroes); } } findHeroesNames().then(function(heroes) { console.log("I've got "+ heroes.length+" heroes"); //prints the array of heroes object return heroes.map(item => item.supepower); // could return another async operation }).then(function(heroesPowers) { console.log(heroesPowers); //prints ["Cleverness", "Friend of Batman"] }).catch(function (err) { console.log("Something went wrong here: "+err); });
  • 66. DAY TWO - BUILTIN FEATURES Promises - Branching Il branching aggancia la stessa promise a multipli callback (invocati parallelamente) Esempio di una Promise Branch let heroes = [{name: "Batman", superpower:"Cleverness"}, {name: "Robin", superpower: "Friend of Batman"} ]; let findHeroes = function() { return new Promise(resolve, reject) { if (heroes) resolve(heroes); else reject(heroes); } } let findPromise = findHeroesNames(); findPromise.then(function(heroes) { console.log("I've got "+ heroes.length+" heroes"); return heroes.map(item => item.supepower); }); findPromise.then(function(heroes) { // still receiving heroes instead of heroes name!!! console.log(heroes); }); 66
  • 67. DAY TWO - ECMASCRIPT6 MODULES Importing and Exporting Nella vecchia concezione di client javascript per utilizzare variabili attraverso vari files occorreva definire variabili globali, causando la proliferazione di oggetti sparsi su tutta l' applicazione di cui quasi non era possibile determinare l' origine e avendo come vincolo l' ordine specifico dei file da importare su browser La community JS ha generato negli anni varie soluzioni per ovviare al problema creando degli standard che definiscono i meccanismi di modularizzazione. I piú importanti sono 1. Asynchronous Module Definition (AMD) : implementato da RequireJS 2. CommonJS Modules: implementato in Node.js I moduli introdotti in ES6 sono un' evoluzione dei 2 principali contendenti, racchiudono le migliori caratteristiche e ne riducono i difetti. 67
  • 68. DAY TWO - ECMASCRIPT6 MODULES Importing and Exporting The Exports keyword // lib.js export const sqrt = Math.sqrt; export function square(x) { return x * x; } export function diag(x, y) { return sqrt(square(x) + square(y)); } Possiamo ora importare le funzioni in un altro file senza infarcire di variabili l' applicazione 68
  • 69. DAY TWO - ECMASCRIPT6 MODULES Importing and Exporting The Import keyword // main.js import { square, diag } from 'libs'; // picking some exports from lib import * as lib2 from 'lib2'; // importing all exports from lib2, with alias console.log(square(11)); // square is available from lib console.log(diag(4, 3)); // also diag is available console.log(lib2.whateverMethod());// using whateverMethod from lib2 Questo sistema rende piú pulito, ordinato e gestibile il progetto Possiamo esportare in modo totalmente flessibile classi, variabili e funzioni 69
  • 70. DAY TWO - EXERCISE Let's try it... Scrivere una funzione che converta un numero intero in un array che per ogni elemento contiene una cifra del numero. es: digitize(123) output --> [1,2,3] digitize(1230) output --> [1,2,3,0]
  • 71. DAY TWO - EXERCISE Let's try it... Scrivere una funzione che converta un numero intero e restituisca un array che per ogni elemento contiene una cifra di tale numero. es: digitize(123) output --> [1,2,3] digitize(1230) output --> [1,2,3,0] Soluzione const digitize = n => [...`${n}`].map(i => parseInt(i));
  • 72. DAY THREE - TYPESCRIPT Typescript Angular é scritto in questo linguaggio, é un superset di javascript che permette strutture tipizzate nello stile OO (classi e interfacce). Il maggior beneficio é la facilitazione nel supporto degli ambienti di lavoro, error spotting e type checking che finora con javascript risultavano parziali e imprecisi. Esempio di sintassi per un' interfaccia (in questo caso un' entitá) interface GreetingSettings { greeting: string; duration?: number; //nullable properties have question mark color?: string; } let MyGreet: GreetingSettings = {greeting: "Hello", duration: 10, color:blue};
  • 73. DAY THREE - TYPESCRIPT Typescript Sintassi di dichiarazione di variabili [accessor] [identifier] : [type-annotation] = [value]; sia l' annotazione del tipo che il valore sono opzionali, omettendo la type annotation il tipo sará any (non consigliato), omettendo il valore la variabile é inizializzata a undefined. private x: Widget = getWidget(1); Sintassi di dichiarazione di una funzione [accessor] [identifier]( [argumentName]: [argumentType] ): [type-annotation];
  • 74. DAY THREE - TYPESCRIPT Typescript - Interfaces and classes interface Drivable { start(): void; drive(distance: number): boolean; } class Car implements Drivable { private _isRunning: boolean; constructor() { this._isRunning = false; } public start() { this._isRunning = true; } public drive(distance: number): boolean { if (this._isRunning) { return true; } return false;
  • 75. DAY THREE - TYPESCRIPT Typescript - Interfaces and classes Un parametro dichiarato nel costruttore diventa una proprietá della classe export class Hero { constructor( public id: number, public name: string, public power: string, public alterEgo?: string ) { } stringify(): string { return this.id + "-"+this.name; //properties into this object
  • 76. DAY THREE - TYPESCRIPT Typescript - Using a type variable Data una semplice classe class Hero { id: number; name: string; } dichiariamo e inizializziamo la variabile hero: Hero = { id: 1, name: "Batman"}; oppure: hero: Hero = new Hero();
  • 77. DAY THREE - TYPESCRIPT Typescript - Features Overloading functions public getWidget(n: number): Widget; public getWidget(n: string): Widget; Type Alias type GreetingLike = string | (() => string) | MyGreeter; private greet(g: GreetingLike): void;
  • 78. DAY THREE - TYPESCRIPT Typescript - Features Namespaces Per organizzare le classi in diversi contesti namespace GreetingLib.Options { // Refer to via GreetingLib.Options.Log interface Log { verbose?: boolean; } interface Alert { } }
  • 79. DAY THREE - ANGULAR Angular - A beginner guide 79
  • 80. DAY THREE - ANGULAR Angular - A beginner guide Angularjs (1.x), Angular 2, 4, 5 or 6?? 80
  • 81. DAY THREE - ANGULAR OVERVIEW Angular - Overview Angular é un framework per sviluppare applicazioni client (browser) single page che riunisce i migliori design pattern della storia di javascript in un' unica soluzione Modules: i moduli di angular (NgModules) definiscono un contesto di compilazione di un set di componenti dedicati a un particolare dominio applicativo. Components: i componenti controllano una parte dello schermo e separano la logica di presentazione dall' aspetto grafico dell' app, assumendo il compito di Controller/ViewModel nel modello MVVM Services: i servizi sono una categoria di oggetti iniettabili sui componenti e progettati per eseguire specifici task. Permettono ai componenti di occuparsi della sola logica di visualizzazione rendendoli piú efficienti e semplificati 81
  • 82. DAY THREE - ANGULAR OVERVIEW Angular - Overview Directives: come i componenti, si occupano di cambiare l' aspetto della parte DOM di cui sono responsabili Templates: utilizzati dai components, i template rappresentano l' aspetto grafico dell' applicazione, ossia la View sul modello MVVM Injector: é un elemento fondamentale di Angular, che si preoccupa di fornire i servizi ai componenti in modo dichiarativo 82
  • 83. DAY THREE - ANGULAR OVERVIEW Angular - Brief FUNDAMENTALS of MVVM É un pattern architetturale che si propone la separation of concerns, ossia che ogni categoria di elementi costituenti un software svolgano determinati e precisi compiti. Si compone di: Model: é il modello di dominio (o una sua derivazione), ció che rappresenta la struttura di dati che si vuole visualizzare e gestire. View: la vista rappresenta il layout e la user experience dell' app. Non dovrebbe contenere logica se non strettamente collegata all' aspetto grafico di cosa vede l'utente View-Model: é l' intermediario tra il modello di business e il modello. “Il view-model fornisce quindi i dati dal modello in una forma che la vista può usare facilmente.”
  • 84. DAY THREE - ANGULAR OVERVIEW Angular - Ecosystem Angular Cli (former DevKit) sistema comprensivo per lo sviluppo, gestione e deploy dei progetti Node.js[v8+] and npm server js e package manager per installare librerie di progetto TypeScript un linguaggio tipizzato che compila in javascript Jasmine/Protractor framework per test unitari e e2e .....continua
  • 85. DAY THREE - ANGULAR OVERVIEW Angular - Ecosystem TypeScript il nuovo linguaggio tipizzato che compila in js Webpack 4 il tool per la build e packaging Angular Cli (former DevKit) sistema comprensivo per lo sviluppo, gestione e deploy dei progetti Node.js[v8+] and npm server js e package manager per installare librerie di progetto Jasmine/Protractor framework per test unitari e e2e
  • 86. DAY THREE - ANGULAR ARCHITECTURE Architettura del flusso dei componenti
  • 87. DAY THREE - ANGULAR ARCHITECTURE Anatomia di un NgModule
  • 88. DAY THREE - ANGULAR ARCHITECTURE NgModule Un modulo Angular racchiude, dichiara e rende disponibili componenti e servizi. Dichiarazione dei metadati (decoration): imports [] dichiarazione di tutti i moduli che si vogliono utilizzare exports [] componenti e servizi visibili all' esterno del modulo declarations [] componenti che il modulo utilizza bootstrap [] il componente root che angular inizializza nel file index.html
  • 89. DAY THREE - ANGULAR ARCHITECTURE Data binding Business Logic (TypeScript) Template View (usually HTML) SYNCHRONIZATION
  • 90. DAY THREE - ANGULAR ARCHITECTURE Data binding Interpolation Binding (One-way component-to-view) <p>4 + 4 = {{4+4}}</p> <p>My favourite hero is {{hero.name}}</p> Property Binding/Attribute/Css Class (One-way component-to-view) <img [src]="product.imageUrl" [title]='product.productName'/> <th [attr.colspan]="2" class="txtcenter"></th> <td [class.txtright]="{{booleanExpression}}">Hero Details</th>
  • 91. DAY THREE - ANGULAR ARCHITECTURE Data binding Event Binding (One-way view-to-component) <button (click)="updateProduct()"> Update </button> Two-Way Binding <input type="text" [(ngModel)]="firstName">
  • 92. DAY THREE - ANGULAR ARCHITECTURE Pipes (operatore | ) I Pipes sono disegnati allo scopo di trasformare i valori degli oggetti (piú complessi di Number, String) in un formato rivolto alla visualizzazione dei dati su schermo. Esempio di una pipe built in per trasformare le Date sulla view di un componente: <p>Your birthday is {{ birthday | date }}</p> //formato di default <p>Your birthday is {{ birthday | date:"MM/dd/yy" }} </p>//formato specifico
  • 93. DAY THREE - ANGULAR ARCHITECTURE Pipes(operatore | ) - Built-in DatePipe {{ value_expression | date [ : format [ : timezone [ : locale ] ] ] }} UpperCasePipe, {{ value_expression | uppercase }} LowerCasePipe {{ value_expression | lowercase }} CurrencyPipe {{ value_expression | currency [ : currencyCode [ : display [ : digitsInfo [ : locale ] ] ] ] }} PercentPipe {{ value_expression | percent [ : digitsInfo [ : locale ] ] }}
  • 94. DAY THREE - ANGULAR ARCHITECTURE Pipes(operatore | ) - Custom @Pipe (decorator):definisce un nuovo Pipe agganciata a una classe PipeTransform (interface): la classe del pipe implementa questa classe che espone un metodo transform(value, param1,param2..paramN) di cui il primo parametro é il valore che si deve convertire, gli altri eventuali parametri in input import { Pipe, PipeTransform } from '@angular/core'; @Pipe({name: 'exponential'}) export class ExponentialPipe implements PipeTransform { transform(value: number, exponent: string): number { let exp = parseFloat(exponent); return Math.pow(value, isNaN(exp) ? 1 : exp); } } Uso nella view <p> Super Hero Power: {{power | exponential: factor}} </p>
  • 95. DAY THREE - ANGULAR ARCHITECTURE Pipes (operatore | ) - Pure e inpure Pipe Pure:eseguite ogni volta che un cambio nel valore (primitivo o ref. dell' oggetto) viene rilevato Pipe Inpure: eseguite ogni volta che un cambio nel componente viene rilevato @Pipe({ name: 'myTransformImpure', pure: false })
  • 96. DAY THREE - ANGULAR ARCHITECTURE Pipes (operatore | ) - Filtrare e ordinare liste In angularjs (1.x) esistevano le pipe filter e orderBy, sono state omesse per problemi di performance e minificazione Si raccomanda di spostare la logica di filtering/ordering dentro il componente
  • 97. DAY THREE - ANGULAR ARCHITECTURE Angular CLI E' uno strumento a riga di comando eseguibile che va installato tramite npm (-g flag per utilizzo a livello globale) Permette di generare struttura del progetto, ng-modules (non js modules), componenti, servizi e altro, eseguire la build per la generazione del pacchetto di distribuzione, eseguire i test e lanciare l' app.
  • 98. DAY THREE - ANGULAR ARCHITECTURE Angular CLI - Principali features Comando Descrizione ng new Creazione di progetto ng generate Generazione modules, components, routes, services & pipes ng serve Lancio dell'applicazione ng build Build e creazione distribuzione ng test Avvio test unitari ng e2e Avvio test e2e ng lint Usa un linter (controllo di errori) sul codice
  • 99. DAY THREE - TUTORIAL Tutorial TOUR OF HEROES - PART 1 ANGULAR CLI
  • 100. DAY THREE - ANGULAR ARCHITECTURE Change detection La Change Detection é una caratteristica fondamentale di Angular, consiste nel rilevare i cambiamenti nel modello e nella vista, sincronizzarli autonomamente e notificare i listener registrati Cosa causa i cambiamenti? - Eventi (click del pulsante, submit di form, selezione di una option da combo) - Chiamate Remote (fetch di dati su server) - Timers (timeouts & intervals) in generale, qualsiasi operazione asincrona
  • 101. DAY THREE - ANGULAR ARCHITECTURE Components I Component sono i building block che controllano porzioni di schermo Si implementano su due entitá distinte (component-class e component-view) Una component-view puó contenere altri child components Nella definizione della component-class si specifica il tag html che permette ad angular di includere il component
  • 102. DAY THREE - ANGULAR ARCHITECTURE Component declaration & Change detection in action Component class (hero.component.ts) @Component({ selector: 'app-heroes', templateUrl: './heroes.component.html', styleUrls: ['./heroes.component.css'] }) export class HeroesComponent implements OnInit { text = 'Some text to change'; constructor() {} changeText() { this.text = 'Another longer longer text to change'; } } View template (hero.component.html) <div> <label>My text is {{text}}</label> <button (click)="changeText()">Change</button> </div>
  • 103. DAY THREE - ANGULAR ARCHITECTURE Component in depth - @Input Struttura parent-child component parent-view <app-child [childMessage]="'myMessage'"></app-child> child-component export class ChildComponent { @Input() childMessage: string; constructor() { } }
  • 104. DAY THREE - ANGULAR ARCHITECTURE Component in depth - @Output parent-view <app-child (messageEvent)="receiveMessage($event)"></app-child> parent-component export class ParentComponent { constructor() { } receiveMessage($event) { this.message = $event } } child-component export class ChildComponent { @Output() messageEvent = new EventEmitter<string>(); message = "Hello" constructor() { } sendMessage() { this.messageEvent.emit(this.message) } }
  • 105. DAY THREE - ANGULAR ARCHITECTURE Component in depth - LifeCycle Hooks Angular gestisce tutto il ciclo di vita di un componente (create, init, change detection, destroy). Ogni componente puó definire delle funzioni richiamate da angular durante le varie fasi. Le piú importanti sono ngOnChanges(SimpleChanges) - richiamata ogni qualvolta uno o piú @input cambiano di valore ngOnInit() - richiamata una sola volta dopo ngOnChanges ngDoCheck() - richiamata ad ogni change detection (N.B. molto pericolosa se non la si usa bene) ngOnDestroy() - richiamata prima che angular distrugga il component (utile per rilasciare risorse ed evitare memory leaks)
  • 106. DAY FOUR - ANGULAR FUNDAMENTALS Forms and Validation Angular gestisce gli elementi dei form (input, select, checkbox...) usando il databinding two-way per sincronizzare il model con la view <input [(ngModel)]="hero.name" placeholder="name"/> Se occorre essere notificati, ad esempio ad ogni carattere digitato sulla input, si aggancia un event-binding con una funzione <input (keyup)="onKey($event)"> //onKey is a function of the component N.B: Gli event binding possono passare degli oggetti particolari, gli $event, che contengono anche l' elemento HTML che scatena l' evento, in questo caso un InputEvent
  • 107. DAY FOUR - ANGULAR FUNDAMENTALS Forms and Validation É possibile sfruttare le direttive per il binding di dati <select [(ngModel)]="hero.power" name="power"> <option *ngFor="let pow of hero.powers" [value]="pow">{{pow}}</option> </select> verrá renderizzata una option per ogni power (array) dell' hero
  • 108. DAY FOUR - ANGULAR FUNDAMENTALS Forms and Validation import {FormsModule} from '@angular/forms'; Per attivare le funzionalitá built-in dei Forms, dichiarare nel modulo (solitamente nel root module) @NgModule({ imports: [ FormsModule, ... ] })
  • 109. DAY FOUR - ANGULAR FUNDAMENTALS Forms and Validation Classi css applicate all' elemento in base al suo stato nel form
  • 110. DAY FOUR - ANGULAR FUNDAMENTALS Forms and Validation Dichiarazione di una variabile (nella view) <input name="name" required [(ngModel)]="hero.name" #name="ngModel" > Utilizzo dei validator (required é anche una direttiva ng!!!) <div class="error" *ngIf="name.invalid && (name.dirty || name.touched) && name.errors.required"> Name is required. </div> N.B.: errors contiene un oggetto con tutti i tipi di errore rilevati per quell' elemento
  • 111. DAY FOUR - ANGULAR FUNDAMENTALS Forms and Validation - Reactive import {ReactiveFormsModule} from '@angular/forms'; Per attivare le funzionalitá built-in dei Forms, dichiarare nel modulo (solitamente nel root module) @NgModule({ imports: [ ReactiveFormsModule, ... ] })
  • 112. DAY FOUR - ANGULAR FUNDAMENTALS Forms and Validation - Reactive Reactive Forms é una variante alla gestione dei Forms classica. In questa formula la variabile del form denominata "name" é dichiarata nel component name = new FormControl(this.hero.name); sulla view <input type="text" [formControl]="name"> Come form: heroForm = new FormGroup({ 'name': new FormControl(this.hero.name, [Validators.required]) })
  • 113. DAY FOUR - ANGULAR FUNDAMENTALS Forms and Validation - Reactive I Custom Validators sono funzioni che accettano un AbstractControl in input myValidator: {[key: string]: any} = (control: AbstractControl) => { let wrongValue = wrongRegExp.test(control.value); return wrongValue ? {'wrongMessageKey': {value: control.value}} : null; } (aderiscono all' interfaccia ValidatorFn) dopodiché aggiungerlo heroForm = new FormGroup({ 'name': new FormControl(this.hero.name, [Validators.required]) }) N.B. Si possono creare anche attribute direttive nel caso si opti per un approccio "view" (vedere tutorial angular)
  • 114. DAY FOUR - ANGULAR FUNDAMENTALS Forms and Validation - Dynamic Dynamic forms é una strategia di creazione (dinamica) dei Form. i singoli campi (form controls) si descrivono tramite oggetti. export class DropdownControl extends BaseControl { //definire BaseControl come superclasse di tutti i controlli controlType = 'dropdown'; options: {key: string, value: string}[] = []; } nella view (ciclando i form controls) <div [ngSwitch]="control.controlType"> <select [id]="control.key" *ngSwitchCase="'dropdown'" [formControlName]="control.key"> <option *ngFor="let opt of control.options" [value]="opt.key">{{opt.value}}</option> </select> ...other switch case </div>
  • 115. DAY FOUR - TUTORIAL Tutorial TOUR OF HEROES - PART 2 COMPONENTS
  • 116. DAY FOUR - ANGULAR ARCHITECTURE Directives Component <app-messages></app-messages> Structural directive (manipolano gli elementi html, es: aggiungono o rimuovono nodi dal DOM) <li *ngFor="let hero of heroes"> Attribute directive <li [ngStyle]="{'font-size.px':24}"></li>
  • 117. DAY FOUR - ANGULAR ARCHITECTURE Attribute Directives Non hanno bisogno di dichiarare template Cambiano l' aspetto dell' elemento a cui sono agganciate @Directive decorator (https://angular.io/api/core/Directive) @Directive({ selector: '[appHighlight]' }) export class HighlightDirective { constructor(el: ElementRef) { el.nativeElement.style.backgroundColor = 'yellow'; } } Uso nella view
  • 118. DAY FOUR - ANGULAR ARCHITECTURE Structural Directives - Main Built-in features ngFor : interpreta una espressione di angular ciclando gli elementi di un array in input. <li *ngFor="let hero of heroes">{{hero.name}}</li> il risultato sará una transclude di tanti elementi <li> quanti sono i valori nell' array heroes e contenenti ognuna il nome dell' hero relativo. altre Features: index: variabile predefinita che rappresenta l'indice dell'array che si sta ciclando tracker: ngFor non permette oggetti duplicati, il tracker serve a definire eventualmente una variabile (ad es. id dell'oggetto o index) che faccia da identificativo della riga renderizzata <div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy:trackById"> ({{i}}) {{hero.name}} </div>
  • 119. DAY FOUR - ANGULAR ARCHITECTURE Structural Directives - Main Built-in features ngIf : interpreta una espressione di angular all'interno del valore dell' attributo con cui é dichiarato (conditional statement if) <div *ngIf="hero.superpower === 'X-Ray Vision'"> <p class="">{{hero.name}} can see through solid objects </p> </div> ngSwitch: unito a ngSwitchCase determina quale dei blocchi che soddisfano la condizione della expression debba essere renderizzata (conditional statement switch) <div [ngSwitch]="person.gender"> <div *ngSwitchCase="'male'">Male</div> <div *ngSwitchCase="'female'">Female</div> <div *ngSwitchDefault>Unknown</app-unknown-hero>
  • 120. DAY FOUR - TUTORIAL Tutorial TOUR OF HEROES - PART 3 DISPLAY DATA
  • 121. DAY FOUR - ANGULAR ARCHITECTURE Services I services svolgono compiti specifici con uno scopo molto ristretto (single responsability), ad esempio occuparsi delle notifiche all' utente, loggare messaggi, effettuare chiamate al server per un determinato ambito Il metadata @Injectable({ providedIn: 'root' }) permette di evitare la definizione del servizio su ogni modulo che necessita di usarlo @Injectable({ providedIn: 'root' }) export class Logger { log(msg: any) { console.log(msg); } error(msg: any) { console.error(msg); } warn(msg: any) { console.warn(msg); } }
  • 122. DAY FOUR - ANGULAR FUNDAMENTALS Dependency injection - Providers Un DI Provider configura un' istanza di servizio iniettabile nei componenti fornendo un contesto di propagazione (component tree). É dichiarato: In un metadato sulla definizione di modulo providers : [Logger] oppure providers : [{ provide: Logger, useClass: BetterLogger }] nel primo caso dichiaro l' implementazione diretta della classe, nel secondo una diversa classe che estende la classe Logger In un metadato (aka decoration) sulla definizione di un servizio @Injectable({ // we declare that this service should be created // by any injector that includes HeroModule. providedIn: HeroModule })
  • 123. DAY FOUR - ANGULAR FUNDAMENTALS Dependency injection - Hierarchy Il Root Injector fornisce la stessa istanza di servizio (singleton) a tutti i componenti. NB: Nella stragrande maggioranza dei casi é sufficiente configurare i servizi in singleton sul root Injector
  • 124. DAY FOUR - ANGULAR FUNDAMENTALS Dependency injection - Contesto Globale o Locale? Il decoratore @Injectable nel seguente caso configura il servizio per essere usato solo nel modulo (e i relativi componenti) HeroModule, import { Injectable } from '@angular/core'; import { HeroModule } from './hero.module'; import { HEROES } from './mock-heroes'; @Injectable({ // we declare that this service should be created // by any injector that includes HeroModule. providedIn: HeroModule, }) export class HeroService { getHeroes() { return HEROES; }
  • 125. DAY FOUR - ANGULAR FUNDAMENTALS Observables powered by RxJs Gli Observables rendono piú facile la gestione di operazioni asincrone (come ad esempio le fetch di dati da server) attraverso un sistema di Publisher/Subscriber Pattern Observer: un oggetto subject contiene una lista di oggetti observers e li notifica automaticamente ad ogni cambio di stato Sono l'evoluzione delle Promises (in Angular si usano al posto di queste ultime, importando la relativa libreria)
  • 126. DAY FOUR - ANGULAR FUNDAMENTALS Observables Un Observer si sottoscrive (subscribe) a un Observable per essere notificato di uno state change Subcribe: la subscribe accetta un oggetto Observer che contiene con tre metodi or da 1 a 3 funzioni in input 1. next(output) funzione richiamata dal subscriber ogni volta che uno stato é variato 2. error: funzione richiamata dal subscriber in caso di errore 3. complete: funzione richiamata dal subscriber quando si chiuderanno le next (eventualmente per richiamare unsubscribe())
  • 127. DAY FOUR - ANGULAR FUNDAMENTALS Observables Esempio di utilizzo su un service (hero.service.ts) che esegue il fetch di dati su server getHeroes (): Observable<Hero[]> { return this.http.get<Hero[]>(this.heroesUrl); } Esempio di utilizzo lato componente (hero.component.ts): ngOnInit() { this.heroService.getHeroes().subscribe(heroes => this.heroes = heroes); }
  • 128. DAY FOUR - TUTORIAL Tutorial TOUR OF HEROES - PART 4 SERVICES
  • 129. DAY FIVE - ANGULAR FUNDAMENTALS Routing, Navigation and Parameters Il Router integrato di Angular permette di navigare l' applicazione da una vista all' altra
  • 130. DAY FIVE - ANGULAR FUNDAMENTALS Routing, Navigation and Parameters The Routes Object export declare type Routes = Route[]; The Route Object {path: 'dashboard', component: DashboardComponent}
  • 131. DAY FIVE - ANGULAR FUNDAMENTALS Routing, Navigation and Parameters import {RouterModule, Routes} from '@angular/router'; Dichiarare nel modulo (root module o module separato) const routes: Routes = [ {path: '', redirectTo: '/dashboard', pathMatch: 'full'}, {path: 'dashboard', component: DashboardComponent}, {path: 'list', component: ListComponent}, {path: 'detail/:id', component: DetailComponent}, ]; @NgModule({ imports: [ RouterModule.forRoot(routes), ... ] })
  • 132. DAY FIVE - ANGULAR FUNDAMENTALS Routing, Navigation and Parameters The Router Outlet Component //dichiarato su app.component.html (in una configurazione di base) <router-outlet></router-outlet> Inserendo questo componente nella view del componente root, quando il browser naviga su una determinata pagina, verrá attivato il relativo componente
  • 133. DAY FIVE - ANGULAR FUNDAMENTALS Routing, Navigation and Parameters - Links Abbiamo analizzato la configurazione, ma come si definiscono i link per attivare un componente successivo? <a routerLink="/list" >Vai alla lista</a> La direttiva routerLink assume il controllo della url, trasforma il path all' interno dell' attributo Perché non usare l' attributo href sull' anchor invece? Perché questa direttiva é dedicata ad angular e agisce nel suo contesto, trasformando i parametri ad esempio
  • 134. DAY FIVE - ANGULAR FUNDAMENTALS Routing, Navigation and Parameters - Links La direttiva routerLinkActive, in congiunzione a routerLink permette di definire classi css nel caso in cui la url del browser corrisponda a quella definita sull' anchor <a routerLink="/list" routerLinkActive="classForAcrive">Vai alla lista</a>
  • 135. DAY FIVE - ANGULAR FUNDAMENTALS Routing, Navigation and Parameters - Passaggio Parametri {path: 'detail/:id', component: DetailComponent} É sufficiente impostare nella view il link come espressione one-way binding <li *ngFor="let hero of heroes"> <a routerLink="/detail/{{hero.id}}"> </li> Il componente attivato puó reperire i parametri attraverso l' oggetto ActivatedRoute iniettabile nel costruttore
  • 136. DAY FIVE - ANGULAR FUNDAMENTALS Routing, Navigation and Parameters - Passaggio Parametri Oggetto Activated Route: contiene info sulla route attualmente attiva, come la url, la configurazione e i parametri (path params & queryString) passati in input definizione in un componente: export class DetailComponent implements OnInit { detailObject: DetailObject; constructor( private route: ActivatedRoute, private detailService: DetailService) {} ngOnInit(): void { const id = +this.route.snapshot.paramMap.get('id'); this.detailService.getDetail(id) .subscribe(detail => this.detailObject = detail); } }
  • 137. DAY FIVE - ANGULAR FUNDAMENTALS Routing, Navigation and Parameters - Nested Routes
  • 138. DAY FIVE - ANGULAR FUNDAMENTALS Routing, Navigation and Parameters - Nested Routes Quando definiamo una Route, aggiungiamo una proprietá children { path: 'list', component: ListComponent, children: [ { path: 'detail/:id', component: DetailComponent } ] } É ora sufficiente aggiungere un <router-outlet> all' interno della view di ListComponent per cambiare il path su browser e visualizzare la sotto-view <li *ngFor="let hero of heroes"> <a routerLink="/detail/{{hero.id}}"> </li> <router-outlet></router-outlet>
  • 139. DAY FIVE - TUTORIAL Tutorial TOUR OF HEROES - PART 5 ROUTING
  • 140. DAY FIVE - ANGULAR FUNDAMENTALS Client HTTP import {HttpClientModule} from '@angular/common/http'; Dichiarazione per l' utilizzo del modulo (nella root solitamente) @NgModule({ imports: [ HttpClientModule, ... ] })
  • 141. DAY FIVE - ANGULAR FUNDAMENTALS Client HTTP Oggetto HttpClient: permette di invocare una url remota con il supporto REST, i metodi: request(...params) all' interno dei parametri (posizionali o a oggetto) é possibile configurare req. method (get, post, put delete), url e varie altre opzioni get(...params) come la request, ma il req. method preimpostato (GET) post(...params) come la request, ma il req. method preimpostato (POST) put(...vari params) come la request, ma il req. method é preimpostato(PUT) delete(...vari params) come la request, ma il req. method é preimpostato(DELETE) Tutti i metodi ritornano un Observable, di seguito trattato
  • 142. DAY FIVE - ANGULAR FUNDAMENTALS Client HTTP Injection in un service export class HeroService { // si puó omettere la dichiarazione della variabile nel service, http // diventa proprietá di HeroService e utilizzabile nei suoi metodi constructor( private http: HttpClient) {}
  • 143. DAY FIVE - TUTORIAL Tutorial TOUR OF HEROES - PART 6 HTTP
  • 144. DAY FIVE - ANGULAR FUNDAMENTALS Unit Testing Predisposizione del Test durante la generazione del componente/servizio con angular-cli Jasmine Framework : lo strumento che mette a disposizione infrastruttura e utility per facilitare la scrittura di test <myComponent>.spec.ts : i file spec contengono i testcase di un componente ng test: shell command per eseguire i test test.ts: contiene la conf e le opzioni per il run dei test con jasmine, di default carica i file *.spec.ts
  • 145. DAY FIVE - ANGULAR FUNDAMENTALS Unit Testing - Testare una unitá Set-up dell' environment di esecuzione (beforeEach) Creazione di una istanza del component/service da testare Creazione del prerequisito per testare il component/service Invocazione del metodo soggetto del test Controllo degli expected behaviours conseguenti all' invocazione
  • 146. DAY FIVE - ANGULAR FUNDAMENTALS Unit Testing - Esempi Esempio di test basico su componente //component export class LightswitchComponent { isOn = false; clicked() { this.isOn = !this.isOn; } } //component.spec.ts describe('LightswitchComponent', () => { it('should toggle #isOn when #clicked()', () => { const comp = new LightswitchComponent(); expect(comp.isOn).toBe(false, 'off at first'); comp.clicked();
  • 147. DAY FIVE - ANGULAR FUNDAMENTALS Esempio di test basico su componente //component export class LightswitchComponent { isOn = false; clicked() { this.isOn = !this.isOn; } } Unit Testing - Esempi
  • 148. DAY FIVE - ANGULAR FUNDAMENTALS //component.spec.ts describe('LightswitchComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [LightswitchComponent] }).compileComponents(); })); it('should toggle #isOn when #clicked()', () => { const fixture = TestBed.createComponent(LightswitchComponent); const app = fixture.debugElement.componentInstance; expect(comp.isOn).toBe(false, 'off at first'); comp.clicked(); Unit Testing - Esempi
  • 149. DAY FIVE - ANGULAR FUNDAMENTALS E2E (End-to-End) Testing banco di prova del codice in un ambiente con browser integrato e interazione con gli elementi HTML (input, buttons ecc ecc..). Il test non conosce la dinamica di funzionamento di componenti e servizi, solo come usare l' interfaccia e i risultati delle operazioni in essa. Protractor framework: lo strumento che mette a disposizione infrastruttura e utility per facilitare la scrittura di test <page>.e2e-spec.ts : i file e2e-spec contengono i testcase di una pagina da testare ng e2e: shell command per eseguire i test e2e protractor.conf.js & tsconfig.e2e.ts: contengono la conf e le opzioni per il run dei test con protractor
  • 150. DAY FIVE - ANGULAR FUNDAMENTALS E2E (End-to-End) Testing - Page Object Pattern Un Page Object (PO) é una classe che descrive l' interfaccia grafica di una pagina i suoi metodi ritornano generalmente elementi presenti nella pagina import { browser, by, element } from 'protractor'; export class HomePage { navigateTo() { return browser.get('/'); } getPageTitle() { return element(by.css('app-home h1.title')).getText(); } } le classi PO hanno convenzionalmente nome con suffisso po.ts
  • 151. DAY FIVE - ANGULAR FUNDAMENTALS E2E (End-to-End) Testing - Testare una pagina Navigazione sulla pagina da testare (beforeEach) Interazione con gli elementi visibili in pagina (fill dati form, click pulsanti) Controllo degli expected values conseguenti (check su etichette, reindirizzamento pagina, messaggi di avvenuta esecuzione, liste aggiornate)
  • 152. DAY FIVE - ANGULAR FUNDAMENTALS E2E (End-to-End) Testing - Testare una pagina Usando la classe PO HomePage si costuisce il test come segue import { HomePage } from './home.po'; describe('workspace-project Home', () => { let page: HomePage; beforeEach(() => { page = new HomePage(); page.navigateTo(); //navigazione e stato iniziale di pagina }); it('should display the title of homepage', () => { expect(page.getPageTitle()).toEqual('Welcome to homepage!'); }); });
  • 153. DAY FIVE - ANGULAR FUNDAMENTALS E2E (End-to-End) Testing - Testare una pagina Esempio di test su cambio di pagina it('Should redirect to the album page when album is clicked', () => { const album = homePage.getAlbumButton(); album.click(); expect(browser.driver.getCurrentUrl()).toContain('/album'); });
  • 154. DAY FIVE - ANGULAR REFERENCES Best Practices and Tutorials Letture: 1. Javascript: The Good Parts http://shop.oreilly.com/product/9780596517748.do Sito ufficiale angular: http://angular.io Organizzazione Progetto: https://medium.com/@michelestieven/organizing-angular- applications-f0510761d65a