Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Ciclo di vita dei componenti

Intercettare le fasi del ciclo di vita di un componente, dall'inizializzazione alla distruzione, sfruttando i Lifecycle Hooks. Con esempi di codice.
Intercettare le fasi del ciclo di vita di un componente, dall'inizializzazione alla distruzione, sfruttando i Lifecycle Hooks. Con esempi di codice.
Link copiato negli appunti

I componenti che costituiscono una applicazione Angular 2 vengono creati dinamicamente in base all'evoluzione dell'applicazione stessa. L'interazione con l'utente e con il server avvia la creazione dei componenti, la loro visualizzazione ed il loro aggiornamento sulla schermata, la loro distruzione. L'esistenza dei componenti durante l'esecuzione dell'applicazione attraversa diverse fasi che ne rappresentano il ciclo di vita. Angular 2 ci consente di intercettare e gestire in maniera personalizzata le varie fasi del ciclo di vita di un componente sfruttando i cosiddetti Lifecycle Hooks: un insieme di eventi in corrispondenza dei quali è possibile definire dei metodi per la loro gestione.

Prima di ogni fase: l'esecuzione del costruttore

Prima di vedere nel dettaglio quali sono le fasi del ciclo di vita dei componenti, è opportuno evidenziare che la prima attività effettuata dal framework alla creazione di un componente è l'esecuzione del suo costruttore. Anche se tecnicamente non rappresenta un Lifecycle Hook, l'esecuzione del costruttore è quindi la fase iniziale della creazione di un componente Angular2. È da evidenziare tuttavia che in questa fase:

  • non sono ancora state inizializzate le proprietà di input;
  • non è ancora disponibile la view associata al componente stesso.

Perciò non è possibile accedere agli elementi del DOM e ai componenti figli. La fase di esecuzione del costruttore rappresenta il momento della creazione dell'istanza del componente ed è quindi utilizzabile per effettuare quelle inizializzazioni che non riguardano il rendering grafico e l'interazione con il framework.

Le fasi del ciclo di vita del componente

Dopo l'esecuzione del costruttore, le seguenti fasi si susseguono in sequenza temporale:

Campo Descrizione
OnChanges Si verifica quando il valore di una proprietà di input viene modificato. Oltre a verificarsi prima dell'inizializzazione del componente, si verifica anche ogni qualvolta cambia il valore delle proprietà di input
OnInit Rappresenta la fase di inizializzazione del componente e si verifica dopo il primo evento OnChanges.
Questa fase viene eseguita una sola volta durante il ciclo di vita del componente.
DoCheck Questa fase viene eseguita durante il check interno di Angular per valutare le modifiche ai componenti ed ai dati. Approfondiremo questo aspetto più avanti nella guida.
AfterContentInit In questa fase il contenuto associato al componente è stato inizializzato; in particolare, è stato costruito l'albero degli eventuali componenti figli.
AfterContentChecked Anche questa fase viene eseguita durante un check interno di Angular sui contenuti associati al componente. Come per la fase di DoCheck, essa risulterà più chiara quando parleremo in maniera più dettagliata del processo di change detection di Angular
AfterViewInit Questa è la fase di inizializzazione della view associata al componente. In questa fase il componente risulta mappato sul DOM ed è quindi visibile.
AfterViewChecked Come per le altre fasi checked, anche in questo caso questa fase riguarda il check interno di Angular sulla view appena generata.
OnDestroy Questa è l'ultima fase del ciclo di vita del componente e si verifica prima che Angular lo distrugga definitivamente.
Questa fase viene eseguita una sola volta durante il ciclo di vita del componente.

In corrispondenza a ciascuna di queste fasi possiamo scrivere il nostro codice per personalizzare il comportamento standard del ciclo di vita del nostro componente. Ad esempio, potremmo intercettare le modifiche ad una proprietà di input per analizzare la variazione del valore e gestirle opportunamente oppure potremmo decidere se visualizzare o meno un elemento del componente previsto dal suo template in base ad una logico più o meno complessa.

Gestire le fasi del component lifecycle

Indipendentemente da cosa e come vogliamo gestire una o più fasi del ciclo di vita di un componente, l'approccio generale consiste nell'implementare una specifica interfaccia TypeScript il cui nome corrisponde alla fase da gestire. Ad esempio, se intendiamo gestire la fase OnInit di un componente dobbiamo implementare l'omonima interfaccia come mostrato di seguito:

import { Component, OnInit } from '@angular/core';
@Component({
	selector: 'articolo',
	templateUrl: 'articolo.component.html',
	styleUrls: ['articolo.component.css']
})
export class ArticoloComponent implements OnInit {
	constructor() { }
	ngOnInit() {
		console.log("Il componente è in fase di inizializzazione!");
	}
}

Rispetto al codice visto negli esempi precedenti possiamo notare l'importazione dell'interfaccia OnInit dalla libreria @angular/core del framework e la dichiarazione di implementazione tramite la clausola implements OnInit. Notiamo anche la presenza del metodo ngOnInit() che rappresenta proprio l'implementazione dell'interfaccia OnInit.

Tutte le interfacce corrispondenti alle fasi del ciclo di vita dei componenti prevedono un solo metodo il cui nome è costituito dal nome della fase preceduto dal prefisso ng. Avremo quindi ngOnChanges() per la gestione della fase OnChanges, ngAfterViewInit() per la gestione di AfterViewInit e così via.

Proviamo a fare un esempio sull'intercettazione delle fasi del ciclo di vita dei componenti e riprendiamo il nostro progetto sulla visualizzazione del testo di un articolo. Supponiamo di voler gestire la codifica di caratteri speciali all'interno del testo. Per chiarire, vorremmo che caratteri come le lettere accentate, dieresi, cediglie ed altro venissero visualizzati correttamente all'interno della view associata al componente e non sostituiti da caratteri strani come nell'esempio mostrato dalla seguente figura:

In JavaScript possiamo ottenere ciò utilizzando la codifica esadecimale. Ad esempio, possiamo visualizzare il carattere è tramite la rappresentazione esadecimale \xE9.

Per semplicità ci concentreremo proprio sulla sostituzione del carattere è all'interno del testo dell'articolo ed utilizzeremo un approccio che intercetta la fase OnChanges del ciclo di vita del nostro componente. Riscriveremo dunque il componente ArticoloComponent come mostrato di seguito:

import { Component, Input, OnChanges, SimpleChange } from '@angular/core';
import { Articolo } from './articolo'
@Component({
	selector: 'articolo',
	templateUrl: 'articolo.component.html',
	styleUrls: ['articolo.component.css']
})
export class ArticoloComponent implements OnChanges {
	@Input() articolo: Articolo;
	ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
		if (changes["articolo"] && changes["articolo"].currentValue.testo) {
			let testoArticolo = changes["articolo"].currentValue.testo;
			changes["articolo"].currentValue.testo = testoArticolo.replace("è", "\xE9") ;
		}
	}
}

Sempre per semplicità, abbiamo riportato soltanto le parti del codice del componente rilevanti per quanto vogliamo discutere.

Notiamo subito l'importazione dell'interfaccia OnChanges e della classe SimpleChange, che descriveremo tra breve. Vediamo anche la dichiarazione dell'implementazione dell'interfaccia OnChanges e la presenza del metodo ngOnChanges() che concretizza tale implementazione.

Il metodo ngOnChanges() prevede il parametro changes la cui struttura è quella di un oggetto con un numero indefinito di proprietà di tipo SimpleChange. L'oggetto changes rappresenta l'elenco delle proprietà di input del componente che sono state modificate. Nel caso del nostro componente abbiamo una sola proprietà di input, articolo, quindi il parametro changes potrà avere al massimo una proprietà articolo con la struttura definita dalla classe SimpleChange.

La classe SimpleChange prevede due proprietà che ci forniscono informazioni sulle variazioni avvenute: previousValue, che rappresenta il valore che la proprietà osservata aveva prima della modifica, e currentValue, che rappresenta il nuovo valore assegnato alla proprietà di input.

Il codice del metodo ngOnChanges() si occupa quindi di verificare se tra le modifiche riportate ce n'è una che coinvolge la proprietà di input articolo e se l'articolo ha la proprietà testo (quest'ultima verifica ci assicura che la proprietà articolo è stata correttamente inizializzata). In caso positivo andiamo a sostituire ogni occorrenza del carattere è con il valore esadecimale \xE9 ed otteniamo il risultato desiderato:

L'estensione di questo approccio per la sostituzione di altri caratteri speciali dovrebbe risultare abbastanza immediato una volta individuati i codici esadecimali corrispondenti.

Ti consigliamo anche