SlideShare a Scribd company logo
1 of 32
Download to read offline
COMPONENTS
Components e Pipe
A cura di Carlotta Dimatteo
ApuliaSoft
apuliasoft.com
Agenda
Components are important!
01
Creare un Component
02
Proprietà e Pipe
03
Components are important!
Big Picture
L’idea alla base
Components
TemplateDirectives
Services
Injector
Event
binding
Property
binding
Components
Proviamo ad individuare i nostri
componenti.
Cosa può e cosa non può essere
un componente?
Keep it simple!
I components sono una key-feature di Angular: possiamo vedere
un’applicazione Angular come una composizione di components
Components
Cosa sono
Costruire e comporre
Components rende
gestibili piccoli pezzi
di un’applicazione
Core di Angular
Ogni Component
ha il suo codice
html. Questo
può essere inline
oppure in un file
html a parte.
Template
Ogni
Component può
avere o meno il
suo style.
Style
Avere diversi
Components
consente di dividere
una applicazione
complessa in parti
riusabili.
Presentation logic
Grazie all’utilizzo dei Components una applicazione sarà più aggiornabile e
manutenibile, senza avere tutta la logica scritta in un unico e affollato script.
Creare un component
Creare un
Component
La CLI genera una nuova folder
src/app/ciccio-list e i tre files relativi
del nostro componente.
ngOnInit è un hook sul ciclo di vita
del componente. Angular chiama
ngOnInit subito dopo aver istanziato il
componente: è il posto migliore per
inserire della logica di inizializzazione.
Lifecycle
Nel file
ciccio-list.component.ts
troviamo il decoratore
@Component con i
relativi metadata:
- selector
- templateUrl
- styleUrls
@Component
Quando iniziamo
un’applicazione, abbiamo
tutto in un unico
componente
(il root-component).
Prendiamo come esempio la
pagina hacker-news.
Individuiamo il bisogno di generare
un componente ‘lista’ che contenga
e renderizzi i dati contenuti nel file
database.ts
ng generate component ciccio-list
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'hn-ciccio-list',
templateUrl: './ciccio-list.component.html',
styleUrls: ['./ciccio-list.component.css']
})
export class CiccioListComponent implements OnInit {
constructor() { }
ngOnInit() {}
}
Creare un
Component
Nel momento in cui si dovesse
creare un Component a mano
bisogna importare il componente
nel app.module.ts e aggiungerlo
nelle declarations
La Angular CLI si occupa
di aggiornare anche il file
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { CiccioListComponent } from './ciccio-list/ciccio-li
st.component';
@NgModule({
declarations: [
AppComponent,
CiccioListComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Proprietà
Data binding
<h3>{{title}}</h3>
Il testo o l’espressione tra le parentesi
corrisponde di solito ad una property del
component e viene calcolato dinamicamente.
Interpolation {{…}}
Il data-binding ci consente di ottenere e settare i valori degli elementi del DOM dinamicamente. Angular si occupa di gestire cio’
che l’utente vede e puo’ fare grazie all’interazione tra l’istanza di classe di un componente e il template HTML che si interfaccia
all’utente.
@Component({
…
})
export class CiccioListComponent
implements OnInit {
description = 'questo è un elemento d
i ciccio-list!';
constructor() {
}
ciccio-list.component.ts
È il meccanismo che consente di coordinare ciò che l’utente vedrà con dati e valori dell’applicazione
<p>
{{description}}
</p>
Data binding
Il data-binding ci consente di ottenere e settare i valori degli elementi del DOM dinamicamente. Angular si occupa di gestire cio’
che l’utente vede e puo’ fare grazie all’interazione tra l’istanza di classe di un componente e il template HTML che si interfaccia
all’utente.
@Component({
…
})
export class CiccioListComponent
implements OnInit {
description = 'questo è un elemento d
i ciccio-list!';
sayMyName() {
console.log(this.description);
}
ciccio-list.component.ts
È il meccanismo che consente di coordinare ciò che l’utente vedrà con dati e valori dell’applicazione
(click)=“deleteThing()”
Risponde ad un evento sollevato dal binding
target (un elemento, un componente o una
direttiva). Questa risposta ha quindi un side-
effect.
Template statements
<p (click)="sayMyName()">
{{description}}
</p>
Data binding
One-way
Dal dato alla view
{{expression}}
[target]="expression"
bind-target="expression"
One-way
Dalla view al dato
(target)="statement"
on-target="statement"
Two-way
Bidirezionale
[(target)]="expression"
bindon-target="expressio
n"
Angular può gestire questi diversi tipi di data-binding
AKA
Banana in the box
Direttive strutturaliLe direttive sono responsabili della manipolazione degli elementi del DOM, quindi del nostro layout definito nel template HMTL. Le
direttive danno forma a questo layout consentendo l’aggiunta, rimozione e manipolazione degli elementi.
La direttiva viene applicata direttamente
ad un elemento host e ai suoi figli.
Elemento Host
01
Le direttive di Angular sono precedute
da un asterisco (*). Nient’altro.
Riconoscibili
02
Angular consente la creazione di
direttive custom che integrino quelle già
disponibili.
Direttive custom
03 *ngFor, *ngIf,
*ngModel….
Direttive strutturali
Questa direttiva ci consente di
ciclare su un array e generare i
relativi elementi del DOM
*ngFor
Le direttive sono responsabili della manipolazione degli elementi del DOM, quindi del nostro layout definito nel template
HMTL. Le direttive danno forma a questo layout consentendo l’aggiunta, rimozione e manipolazione degli elementi.
@Component({
…
})
export class CiccioListComponent{
descriptions = [
'sono il primo elemento',
'sono il secondo elemento',
'sono il terzo elemento!'
];
}
ciccio-list.component.ts
Se ad esempio volessimo vedere una lista di description nel nostro ciccio-list Component potremmo usare…
<p>Description:</p>
<ul>
<li (click)="sayMyName(description)"
*ngFor="let description of descriptions">
{{ description }}
</li>
</ul>
*ngFor
I nostri elementi vengono visualizzati
correttamente! Se clicchiamo su uno
di essi vedremo in console la stessa
descrizione…
La direttiva *ngFor si è occupata di
generare tanti elementi quanti quelli
presenti nell’array descriptions. Per
ognuno di essi le proprietà di data-
binding sono ancora valide!
Nel DOM
Vediamo cosa è successo dopo aver
applicato la nostra direttiva…
È il tuo
turno! 1. Facciamo il clone di questo progetto:
git clone https://bitbucket.org/apuliasoft/hackernews-tutorial.git
2. Per installare tutte le dipendenze necessarie lanciamo il
comando:
npm install
3. Ora digitiamo:
git checkout components-start
In questo modo partiremo tutti con lo stesso progetto.
Creiamo il nostro primo componente del nostro hacker-news
È il tuo
turno! • Creiamo un componente link-list.component. Al suo interno:
- importiamo il tipo Link da types
- importiamo il file database.ts come una costante DATABASE
• Visualizziamo tramite un ciclo ngFor i primi due links contenuti in
DATABASE.
• Per ogni elemento del ciclo dobbiamo visualizzare:
- id, description, url, points e pubData
• Leghiamo al pulsante More un comportamento che ci consenta di
cambiare pagina e visualizzare i successivi due link presenti in
DATABASE.
Creiamo il primo componente del nostro hacker-news
Proprietà e Pipe
Interazione tra componenti
Definiamo delle input properties sul
componente figlio: sarà il dato che
verrà passato da padre a figlio.
Grazie al decoratore @Input
comunichiamo ad Angular che questo
componente riceverà un dato da un
altro componente.
Parent-> Child @Input
I dati fluiscono nel tuo component tramite il property biding e fuoriescono grazie all’event-binding
@Component({
…
})
export class CiccioItemComponent {
@Input() description: string;
}
ciccio-item.component.ts
Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro?
Interazione tra componenti
Nel componente padre vediamo la
proprietà che è un Array di string.
Parent-> Child @Input
Nota: i decoratori @Input e @Output devono essere importati da @angular/core!
@Component({
…
})
export class CiccioListComponent
implements OnInit {
descriptions: string[];
page: number;
}
ciccio-list.component.ts
Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro?
Interazione tra componenti
Nel componente padre (ciccio-
list.component.ts) troviamo innestato il
componente figlio (ciccio-
item.component.ts) all’interno del repeater
*ngFor.
Qui vediamo un binding per ogni iterazione
tra una description del componente padre e
l’istanza del componente figlio.
Parent-> Child @Input
<hn-ciccio-item
*ngFor="let description of descriptio
ns;"
[description]= "description">
</hn-ciccio-item>
ciccio-list.component.html
Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro?
Nota: i decoratori @Input e @Output devono essere importati da @angular/core!
Interazione tra componenti
I dati fluiscono nel tuo component tramite il property biding e fuoriescono grazie all’event-binding
@Component({
…
})
export class CiccioItemComponent {
@Input() description: string;
@Output() sayMyName =new EventEmitter
<string>();
date: Date;
}
ciccio-item.component.ts
Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro?
Il componente figlio espone una proprietà
di tipo EventEmitter, che notifica un certo
evento quando avviene qualcosa.
Child->Parent @Output
Interazione tra componenti
Nota: i decoratori @Input e @Output devono essere importati da @angular/core!
@Component({
…
})
export class CiccioListComponent
implements OnInit {
descriptions: string[];
page: number;
…
sayMyName(description: string) {
…
}
ciccio-list.component.ts
Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro?
Nel padre abbiamo inoltre il
metodo sayMyName: il
parametro gli sarà passato dal
figlio.
Child->Parent @Output
Interazione tra componenti
<hn-ciccio-item
*ngFor="let description of descriptio
ns;"
[description]= "description"
(sayMyName)="sayMyName($event)">
</hn-ciccio-item>
ciccio-list.component.html
Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro?
Bindiamo ad un evento ‘sayMyName’
la chiamata al metodo
corrispondente nel padre.
Child->Parent @Output
Nota: i decoratori @Input e @Output devono essere importati da @angular/core!
Event Emitter
Se vogliamo che il nostro child notifichi al
padre l’avvenimento di un evento
dobbiamo utilizzare EventEmitter .
Child->Parent @Output
@Output() sayMyName =new EventEmitter
<string>();
this.sayMyName.emit(this.description
)
ciccio-item.component.html
(sayMyName)="sayMyName($event)«
ciccio-list.component.html
Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro?
Nota: i decoratori @Input e @Output devono essere importati da @angular/core!
Possiamo vedere Event Emitter come un
Observable. Il componente figlio notifica
infatti un evento ai componenti che si sono
registrati a questo evento.
Angular si sottoscrive a questo evento e
chiamerà il metodo sayMyName().
Event Emitter
Pipe
Trasformazioni sul display-value direttamete nel codice HTML (senza modificare davvero il valore)
Angular fornisce alcuni pipes come:
DatePipe, UpperCasePipe… pronti
all’uso.
Built-in pipes
Prendono in input un valore e lo
trasformano nell’output desiderato.
Il comportamento del pipe può
essere applicato e replicabile per
tutti i dati necessari.
Possiamo creare i pipes che ci
servono: sono parametrizzabili e si
possono usare in chain (anche con
i pipes built-in).
Custom pipes
Pipe
Nel componente abbiamo la
nostra proprietà con il valore
che vogliamo trasformare.
In questo caso new Date()
genera una data nel formato
2018-04-19T12:45:44.360Z
Non è molto leggibile!
Vogliamo trasformarla in
qualcosa che sia comprensibile
immediatamente.
@Component({
…
})
export class CiccioItemComponent {
@Input() description: string;
@Output() sayMyName =new EventEmitter
<string>();
date: new Date();
}
ciccio-item.component.ts
Come si usa
Pipe
Il pipe date viene applicato al valore di
description.date, direttamente nelle
parentesi graffe.
Nel html {{value | pipename }}
<p>
{{ description }},
date : {{description.date | date}}
</p>
ciccio-item.component.html
Come si usa
Pipe
Una classe Pipe implementa il metodo
transform della classe PipeTransform.
Questo metodo accetta un valore di input
(quello che dovrà essere trasformato) e altri
parametri (in questo caso ad esempio
l’esponente).
Il decoratore @Pipe dice ad Angular che
quello è un Pipe e consente inoltre di definire il
nome del Pipe che sarà utilizzato nella nostra
applicazione.
L’utilizzo di un custom pipe è identico a quello
dei built-in pipes.
Come si crea un custom pipe
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'exponentialStrength'})
export class ExponentialStrengthPipe
implements PipeTransform {
transform(value: number, exponent: string): number {
let exp = parseFloat(exponent);
return Math.pow(value, isNaN(exp) ? 1 : exp);
}
}
Nota: a meno che non utilizzi la Angular CLI, quando crei un custom Pipe devi registrarlo
nelle declarations dell’AppModule!
È il tuo
turno! • Creiamo un componente figlio di link-list: link-item.
• All’interno incapsuliamo la logica del singolo item in modo da
essere ripetuto all’interno di una link-list.
• La componente figlio riceverà in input il link
• La componente figlio espone come Output il metodo upvoted
• Colleghiamo un evento upvoted ad ogni link. Il metodo chiamato
dallo scatenarsi di questo evento dovrà incrementare il valore di
points del singolo link.
• Creiamo un pipe di nome moment che utilizzi la libreria
moment.js e sia in grado di restituire il tempo passato dalla
pubblicazione della news al momento della sua visualizzazione.
Suggerimento: utilizzare il metodo fromNow di moment.js
https://momentjs.com/
Aggiungiamo ancora logica e componenti al nostro hacker-news…
And now it’s time for lunch

More Related Content

Similar to Components

Acadevmy - Angular Overview
Acadevmy - Angular OverviewAcadevmy - Angular Overview
Acadevmy - Angular OverviewFrancesco Sciuti
 
DNM19 Sessione2 Orchard Temi e Layout (Ita)
DNM19 Sessione2 Orchard Temi e Layout (Ita)DNM19 Sessione2 Orchard Temi e Layout (Ita)
DNM19 Sessione2 Orchard Temi e Layout (Ita)Alessandro Giorgetti
 
Meetup ASP.NET Core Angular
Meetup ASP.NET Core AngularMeetup ASP.NET Core Angular
Meetup ASP.NET Core Angulardotnetcode
 
Build a LINQ-enabled Repository
Build a LINQ-enabled RepositoryBuild a LINQ-enabled Repository
Build a LINQ-enabled RepositoryAndrea Saltarello
 
Introduzioni ai services in Angular 4 e ad RxJS
Introduzioni ai services in Angular 4 e ad RxJSIntroduzioni ai services in Angular 4 e ad RxJS
Introduzioni ai services in Angular 4 e ad RxJSGiovanni Buffa
 
Javascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesignerJavascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesignerMatteo Magni
 
Web advanced-03-d3 js-base
Web advanced-03-d3 js-baseWeb advanced-03-d3 js-base
Web advanced-03-d3 js-baseStudiabo
 
Dependency injection questa sconosciuta
Dependency injection questa sconosciutaDependency injection questa sconosciuta
Dependency injection questa sconosciutaAndrea Dottor
 
Sviluppo Di Applicazioni Su I Os
Sviluppo Di Applicazioni Su I OsSviluppo Di Applicazioni Su I Os
Sviluppo Di Applicazioni Su I OsNoDelay Software
 
Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2Ivan Gualandri
 
Idiomatic Domain Driven Design
Idiomatic Domain Driven DesignIdiomatic Domain Driven Design
Idiomatic Domain Driven DesignAndrea Saltarello
 
Spring Framework
Spring FrameworkSpring Framework
Spring FrameworkNaLUG
 

Similar to Components (20)

Acadevmy - Angular Overview
Acadevmy - Angular OverviewAcadevmy - Angular Overview
Acadevmy - Angular Overview
 
DNM19 Sessione2 Orchard Temi e Layout (Ita)
DNM19 Sessione2 Orchard Temi e Layout (Ita)DNM19 Sessione2 Orchard Temi e Layout (Ita)
DNM19 Sessione2 Orchard Temi e Layout (Ita)
 
Meetup ASP.NET Core Angular
Meetup ASP.NET Core AngularMeetup ASP.NET Core Angular
Meetup ASP.NET Core Angular
 
Angular - DI tricks
Angular - DI tricksAngular - DI tricks
Angular - DI tricks
 
Build a LINQ-enabled Repository
Build a LINQ-enabled RepositoryBuild a LINQ-enabled Repository
Build a LINQ-enabled Repository
 
Corso angular js componenti
Corso angular js componentiCorso angular js componenti
Corso angular js componenti
 
Introduzioni ai services in Angular 4 e ad RxJS
Introduzioni ai services in Angular 4 e ad RxJSIntroduzioni ai services in Angular 4 e ad RxJS
Introduzioni ai services in Angular 4 e ad RxJS
 
ASP.NET
ASP.NETASP.NET
ASP.NET
 
react-it.pdf
react-it.pdfreact-it.pdf
react-it.pdf
 
Javascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesignerJavascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesigner
 
Web advanced-03-d3 js-base
Web advanced-03-d3 js-baseWeb advanced-03-d3 js-base
Web advanced-03-d3 js-base
 
Riepilogo Java C/C++
Riepilogo Java C/C++Riepilogo Java C/C++
Riepilogo Java C/C++
 
Dependency injection questa sconosciuta
Dependency injection questa sconosciutaDependency injection questa sconosciuta
Dependency injection questa sconosciuta
 
Sviluppo Di Applicazioni Su I Os
Sviluppo Di Applicazioni Su I OsSviluppo Di Applicazioni Su I Os
Sviluppo Di Applicazioni Su I Os
 
Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2
 
Angularjs
AngularjsAngularjs
Angularjs
 
Spring 2.5
Spring 2.5Spring 2.5
Spring 2.5
 
Idiomatic Domain Driven Design
Idiomatic Domain Driven DesignIdiomatic Domain Driven Design
Idiomatic Domain Driven Design
 
Spring Intro
Spring IntroSpring Intro
Spring Intro
 
Spring Framework
Spring FrameworkSpring Framework
Spring Framework
 

Components

  • 1. COMPONENTS Components e Pipe A cura di Carlotta Dimatteo ApuliaSoft apuliasoft.com
  • 2. Agenda Components are important! 01 Creare un Component 02 Proprietà e Pipe 03
  • 4. Big Picture L’idea alla base Components TemplateDirectives Services Injector Event binding Property binding
  • 5. Components Proviamo ad individuare i nostri componenti. Cosa può e cosa non può essere un componente? Keep it simple! I components sono una key-feature di Angular: possiamo vedere un’applicazione Angular come una composizione di components
  • 6. Components Cosa sono Costruire e comporre Components rende gestibili piccoli pezzi di un’applicazione Core di Angular Ogni Component ha il suo codice html. Questo può essere inline oppure in un file html a parte. Template Ogni Component può avere o meno il suo style. Style Avere diversi Components consente di dividere una applicazione complessa in parti riusabili. Presentation logic Grazie all’utilizzo dei Components una applicazione sarà più aggiornabile e manutenibile, senza avere tutta la logica scritta in un unico e affollato script.
  • 8. Creare un Component La CLI genera una nuova folder src/app/ciccio-list e i tre files relativi del nostro componente. ngOnInit è un hook sul ciclo di vita del componente. Angular chiama ngOnInit subito dopo aver istanziato il componente: è il posto migliore per inserire della logica di inizializzazione. Lifecycle Nel file ciccio-list.component.ts troviamo il decoratore @Component con i relativi metadata: - selector - templateUrl - styleUrls @Component Quando iniziamo un’applicazione, abbiamo tutto in un unico componente (il root-component). Prendiamo come esempio la pagina hacker-news. Individuiamo il bisogno di generare un componente ‘lista’ che contenga e renderizzi i dati contenuti nel file database.ts ng generate component ciccio-list import { Component, OnInit } from '@angular/core'; @Component({ selector: 'hn-ciccio-list', templateUrl: './ciccio-list.component.html', styleUrls: ['./ciccio-list.component.css'] }) export class CiccioListComponent implements OnInit { constructor() { } ngOnInit() {} }
  • 9. Creare un Component Nel momento in cui si dovesse creare un Component a mano bisogna importare il componente nel app.module.ts e aggiungerlo nelle declarations La Angular CLI si occupa di aggiornare anche il file app.module.ts import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { CiccioListComponent } from './ciccio-list/ciccio-li st.component'; @NgModule({ declarations: [ AppComponent, CiccioListComponent ], imports: [ BrowserModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
  • 11. Data binding <h3>{{title}}</h3> Il testo o l’espressione tra le parentesi corrisponde di solito ad una property del component e viene calcolato dinamicamente. Interpolation {{…}} Il data-binding ci consente di ottenere e settare i valori degli elementi del DOM dinamicamente. Angular si occupa di gestire cio’ che l’utente vede e puo’ fare grazie all’interazione tra l’istanza di classe di un componente e il template HTML che si interfaccia all’utente. @Component({ … }) export class CiccioListComponent implements OnInit { description = 'questo è un elemento d i ciccio-list!'; constructor() { } ciccio-list.component.ts È il meccanismo che consente di coordinare ciò che l’utente vedrà con dati e valori dell’applicazione <p> {{description}} </p>
  • 12. Data binding Il data-binding ci consente di ottenere e settare i valori degli elementi del DOM dinamicamente. Angular si occupa di gestire cio’ che l’utente vede e puo’ fare grazie all’interazione tra l’istanza di classe di un componente e il template HTML che si interfaccia all’utente. @Component({ … }) export class CiccioListComponent implements OnInit { description = 'questo è un elemento d i ciccio-list!'; sayMyName() { console.log(this.description); } ciccio-list.component.ts È il meccanismo che consente di coordinare ciò che l’utente vedrà con dati e valori dell’applicazione (click)=“deleteThing()” Risponde ad un evento sollevato dal binding target (un elemento, un componente o una direttiva). Questa risposta ha quindi un side- effect. Template statements <p (click)="sayMyName()"> {{description}} </p>
  • 13. Data binding One-way Dal dato alla view {{expression}} [target]="expression" bind-target="expression" One-way Dalla view al dato (target)="statement" on-target="statement" Two-way Bidirezionale [(target)]="expression" bindon-target="expressio n" Angular può gestire questi diversi tipi di data-binding AKA Banana in the box
  • 14. Direttive strutturaliLe direttive sono responsabili della manipolazione degli elementi del DOM, quindi del nostro layout definito nel template HMTL. Le direttive danno forma a questo layout consentendo l’aggiunta, rimozione e manipolazione degli elementi. La direttiva viene applicata direttamente ad un elemento host e ai suoi figli. Elemento Host 01 Le direttive di Angular sono precedute da un asterisco (*). Nient’altro. Riconoscibili 02 Angular consente la creazione di direttive custom che integrino quelle già disponibili. Direttive custom 03 *ngFor, *ngIf, *ngModel….
  • 15. Direttive strutturali Questa direttiva ci consente di ciclare su un array e generare i relativi elementi del DOM *ngFor Le direttive sono responsabili della manipolazione degli elementi del DOM, quindi del nostro layout definito nel template HMTL. Le direttive danno forma a questo layout consentendo l’aggiunta, rimozione e manipolazione degli elementi. @Component({ … }) export class CiccioListComponent{ descriptions = [ 'sono il primo elemento', 'sono il secondo elemento', 'sono il terzo elemento!' ]; } ciccio-list.component.ts Se ad esempio volessimo vedere una lista di description nel nostro ciccio-list Component potremmo usare… <p>Description:</p> <ul> <li (click)="sayMyName(description)" *ngFor="let description of descriptions"> {{ description }} </li> </ul>
  • 16. *ngFor I nostri elementi vengono visualizzati correttamente! Se clicchiamo su uno di essi vedremo in console la stessa descrizione… La direttiva *ngFor si è occupata di generare tanti elementi quanti quelli presenti nell’array descriptions. Per ognuno di essi le proprietà di data- binding sono ancora valide! Nel DOM Vediamo cosa è successo dopo aver applicato la nostra direttiva…
  • 17. È il tuo turno! 1. Facciamo il clone di questo progetto: git clone https://bitbucket.org/apuliasoft/hackernews-tutorial.git 2. Per installare tutte le dipendenze necessarie lanciamo il comando: npm install 3. Ora digitiamo: git checkout components-start In questo modo partiremo tutti con lo stesso progetto. Creiamo il nostro primo componente del nostro hacker-news
  • 18. È il tuo turno! • Creiamo un componente link-list.component. Al suo interno: - importiamo il tipo Link da types - importiamo il file database.ts come una costante DATABASE • Visualizziamo tramite un ciclo ngFor i primi due links contenuti in DATABASE. • Per ogni elemento del ciclo dobbiamo visualizzare: - id, description, url, points e pubData • Leghiamo al pulsante More un comportamento che ci consenta di cambiare pagina e visualizzare i successivi due link presenti in DATABASE. Creiamo il primo componente del nostro hacker-news
  • 20. Interazione tra componenti Definiamo delle input properties sul componente figlio: sarà il dato che verrà passato da padre a figlio. Grazie al decoratore @Input comunichiamo ad Angular che questo componente riceverà un dato da un altro componente. Parent-> Child @Input I dati fluiscono nel tuo component tramite il property biding e fuoriescono grazie all’event-binding @Component({ … }) export class CiccioItemComponent { @Input() description: string; } ciccio-item.component.ts Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro?
  • 21. Interazione tra componenti Nel componente padre vediamo la proprietà che è un Array di string. Parent-> Child @Input Nota: i decoratori @Input e @Output devono essere importati da @angular/core! @Component({ … }) export class CiccioListComponent implements OnInit { descriptions: string[]; page: number; } ciccio-list.component.ts Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro?
  • 22. Interazione tra componenti Nel componente padre (ciccio- list.component.ts) troviamo innestato il componente figlio (ciccio- item.component.ts) all’interno del repeater *ngFor. Qui vediamo un binding per ogni iterazione tra una description del componente padre e l’istanza del componente figlio. Parent-> Child @Input <hn-ciccio-item *ngFor="let description of descriptio ns;" [description]= "description"> </hn-ciccio-item> ciccio-list.component.html Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro? Nota: i decoratori @Input e @Output devono essere importati da @angular/core!
  • 23. Interazione tra componenti I dati fluiscono nel tuo component tramite il property biding e fuoriescono grazie all’event-binding @Component({ … }) export class CiccioItemComponent { @Input() description: string; @Output() sayMyName =new EventEmitter <string>(); date: Date; } ciccio-item.component.ts Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro? Il componente figlio espone una proprietà di tipo EventEmitter, che notifica un certo evento quando avviene qualcosa. Child->Parent @Output
  • 24. Interazione tra componenti Nota: i decoratori @Input e @Output devono essere importati da @angular/core! @Component({ … }) export class CiccioListComponent implements OnInit { descriptions: string[]; page: number; … sayMyName(description: string) { … } ciccio-list.component.ts Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro? Nel padre abbiamo inoltre il metodo sayMyName: il parametro gli sarà passato dal figlio. Child->Parent @Output
  • 25. Interazione tra componenti <hn-ciccio-item *ngFor="let description of descriptio ns;" [description]= "description" (sayMyName)="sayMyName($event)"> </hn-ciccio-item> ciccio-list.component.html Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro? Bindiamo ad un evento ‘sayMyName’ la chiamata al metodo corrispondente nel padre. Child->Parent @Output Nota: i decoratori @Input e @Output devono essere importati da @angular/core!
  • 26. Event Emitter Se vogliamo che il nostro child notifichi al padre l’avvenimento di un evento dobbiamo utilizzare EventEmitter . Child->Parent @Output @Output() sayMyName =new EventEmitter <string>(); this.sayMyName.emit(this.description ) ciccio-item.component.html (sayMyName)="sayMyName($event)« ciccio-list.component.html Cosa facciamo quando due componenti hanno bisogno di comunicare tra loro? Nota: i decoratori @Input e @Output devono essere importati da @angular/core! Possiamo vedere Event Emitter come un Observable. Il componente figlio notifica infatti un evento ai componenti che si sono registrati a questo evento. Angular si sottoscrive a questo evento e chiamerà il metodo sayMyName(). Event Emitter
  • 27. Pipe Trasformazioni sul display-value direttamete nel codice HTML (senza modificare davvero il valore) Angular fornisce alcuni pipes come: DatePipe, UpperCasePipe… pronti all’uso. Built-in pipes Prendono in input un valore e lo trasformano nell’output desiderato. Il comportamento del pipe può essere applicato e replicabile per tutti i dati necessari. Possiamo creare i pipes che ci servono: sono parametrizzabili e si possono usare in chain (anche con i pipes built-in). Custom pipes
  • 28. Pipe Nel componente abbiamo la nostra proprietà con il valore che vogliamo trasformare. In questo caso new Date() genera una data nel formato 2018-04-19T12:45:44.360Z Non è molto leggibile! Vogliamo trasformarla in qualcosa che sia comprensibile immediatamente. @Component({ … }) export class CiccioItemComponent { @Input() description: string; @Output() sayMyName =new EventEmitter <string>(); date: new Date(); } ciccio-item.component.ts Come si usa
  • 29. Pipe Il pipe date viene applicato al valore di description.date, direttamente nelle parentesi graffe. Nel html {{value | pipename }} <p> {{ description }}, date : {{description.date | date}} </p> ciccio-item.component.html Come si usa
  • 30. Pipe Una classe Pipe implementa il metodo transform della classe PipeTransform. Questo metodo accetta un valore di input (quello che dovrà essere trasformato) e altri parametri (in questo caso ad esempio l’esponente). Il decoratore @Pipe dice ad Angular che quello è un Pipe e consente inoltre di definire il nome del Pipe che sarà utilizzato nella nostra applicazione. L’utilizzo di un custom pipe è identico a quello dei built-in pipes. Come si crea un custom pipe import { Pipe, PipeTransform } from '@angular/core'; @Pipe({name: 'exponentialStrength'}) export class ExponentialStrengthPipe implements PipeTransform { transform(value: number, exponent: string): number { let exp = parseFloat(exponent); return Math.pow(value, isNaN(exp) ? 1 : exp); } } Nota: a meno che non utilizzi la Angular CLI, quando crei un custom Pipe devi registrarlo nelle declarations dell’AppModule!
  • 31. È il tuo turno! • Creiamo un componente figlio di link-list: link-item. • All’interno incapsuliamo la logica del singolo item in modo da essere ripetuto all’interno di una link-list. • La componente figlio riceverà in input il link • La componente figlio espone come Output il metodo upvoted • Colleghiamo un evento upvoted ad ogni link. Il metodo chiamato dallo scatenarsi di questo evento dovrà incrementare il valore di points del singolo link. • Creiamo un pipe di nome moment che utilizzi la libreria moment.js e sia in grado di restituire il tempo passato dalla pubblicazione della news al momento della sua visualizzazione. Suggerimento: utilizzare il metodo fromNow di moment.js https://momentjs.com/ Aggiungiamo ancora logica e componenti al nostro hacker-news…
  • 32. And now it’s time for lunch