Da un punto di vista concettuale, un componente Angular è una classe TypeScript a cui vengono applicati uno o più decoratori che descrivono alcune metainformazioni sul componente.
Per chiarire meglio il concetto, in questa lezione iniziamo con il dare un'occhiata alla definizione del root component dell'applicazione generata da Angular CLI per comprendere gli elementi fondamentali della nuova sintassi di Angular 2.
Nel nostro caso il modulo AppModule fa riferimento al componente AppComponent come root component dell'applicazione. Troviamo il root component nel file app.component.ts
. Per convenzione, i nomi dei file che contengono la definizione di componenti hanno la struttura:
nomeComponente.component
Il codice contenuto nel file è il seguente:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app works!';
}
Nel nostro caso il componente è rappresentato dalla classe AppComponent con la sola proprietà title
che descrive il testo da visualizzare sullo schermo.
Il decoratore @Component
Un decoratore è una funzione che prende la una classe e la arricchisce di specifiche funzionalità. Si tratta di uno standard introdotto dalle specifiche ECMAScript 2016 (ES7) e già recepite da TypeScript.
Nel caso di Angular 2, il decoratore @Component
arricchisce la classe di quelle funzionalità che la rendono un componente ed esso viene importato dal modulo @angular/core
del framework.
Nel nostro esempio, al decoratore @Component
vengono passate alcune metainformazioni che determinano come il componente si aggancia al markup. In particolare:
Proprietà | Descrizione |
---|---|
selector | indica l'elemento del markup a cui è agganciato il componente |
templateUrl | indica il file HTML che descrive il markup del componente |
styleUrls | indica l'elenco dei file CSS da applicare al markup |
Questo vuol dire che il componente può essere usato all'interno di una pagina HTML inserendo l'elemento <app-root>
. Notiamo che proprio questo è l'elemento che troviamo nella pagina index.html
della nostra applicazione.
L'elemento a cui si aggancia il root component
della nostra applicazione verrà sostituito dal markup contenuto nel file templateUrl
:
<h1>{{title}}</h1>
Notiamo in questo markup la presenza dell'espressione {{title}}
.
Gli sviluppatori che hanno un minimo di dimestichezza con Angular riconosceranno l'espressione di interpolazione che consente di visualizzare nel markup valori definiti all'interno del componente. Nel caso specifico, all'interno dell'elemento <h1>
verrà visualizzato il valore della proprietà title
.
La definizione dei fogli di stile da applicare al markup determina l'aspetto grafico del componente. Nell'esempio generato da Angular CLI non viene inserita nessuna regola CSS nel file app.component.css
. Se inseriamo delle definizioni, esse saranno applicate al componente. È importante sottolineare che quando assegniamo dei fogli di stile ad un componente, questi hanno effetto soltanto sul componente e sui suoi discendenti, ma non influenzano il markup e i componenti esterni.
È utile sottolineare come la classe AppAppComponent
sia preceduta dalla clausola export
. Questo fa sì che il componente sia accessibile all'esterno del modulo corrente. Se non specifichiamo questa parola chiave il nostro componente non sarà disponibile al di fuori del modulo corrente.
Possiamo accedere al componente definito nel modulo utilizzando la clausola import
, come abbiamo avuto modo di vedere nei vari esempi di codice analizzati.
Il codice che abbiamo analizzato è quello generato automaticamente da Angular CLI. Ci è servito come punto di partenza per comprendere come è fatto un componente Angular, ma naturalmente possiamo modificarlo a nostro piacimento. La cosa fondamentale da tener presente che sostanzialmente un componente è una classe a cui è applicato il decoratore @Component
. Al posto della proprietà templateUrl
avremmo potuto utilizzare la proprietà template
e scrivere il markup direttamente all'interno del componente, come nel seguente esempio:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: '<h1>{{title}}</h1>'
})
export class AppComponent {
title = 'app works!!!';
}
Questo approccio è utile quando il markup è talmente compatto che non vale la pena creare un file apposito. Lo stesso discorso vale per l'applicazione dei fogli di stile. In questo caso al posto della proprietà styleUrls
avremmo potuto usare la proprietà styles
, come mostrato di seguito:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: '<h1>{{title}}</h1>',
styles: ['h1 {color: red}']
})
export class AppComponent {
title = 'my-app works!!!';
}
TypeScript vs ES5
Quando abbiamo introdotto Angular 2 abbiamo detto che possiamo sviluppare applicazioni Web con TypeScript, ma anche con puro JavaScript secondo le specifiche ES5. A semplice titolo di curiosità, riportiamo il codice JavaScript equivalente al componente appena definito:
(function(app) {
app.MyAppAppComponent =
ng.core.Component({
selector: 'app-root',
template: '<h1>{{title}}</h1>',
styles: ['h1 {color: red}']
})
.Class({
constructor: function() {
this.title = 'app works!!!';
}
});
})(window.app || (window.app = {}));
Come possiamo già intuire da questo esempio minimale, l'approccio con ES5 risulta alquanto prolisso e rischia di diventare ingestibile con componenti complessi.