Angular day 2018, ep. 5: i nuovi Angular Elements raccontati da Michele Stieven

Angular day 2018: Michele Stieven ci insegna a trasformare i componenti Angular in Custom Elements riutilizzabili in qualsiasi applicazione JavaScript… forse.

Uno dei problemi “storici” di Angular √® sempre stata la difficolt√† di utilizzare componenti Angular in applicazioni costruite con altri framework (widget). Questo ha reso la riusabilit√† dei componenti e l’integrazione quantomeno problematici.


Con Angular Elements √® possibile riutilizzare questi componenti in interfacce utenti “framework agnostic”, ed √® possibile costruire elementi custom in modo semplice, con un codice di questo genere:

class LoadingSpinner extends HTMLElement { ... } 
customElements.define('loading-spinner', LoadingSpinner);

Da notare che customElement √® un Web Component standard, e cos√¨ come la propriet√†¬†customElements¬†sono oramai uno standard, gi√† incluso in Chrome, IE10, Edge e Safari. L’utilizzo nella pagina HTML √® altrettanto semplice:

<my-element someAttribute=‚ÄĚsomevalue‚ÄĚ></my-element>

SomeAttribute è un attributo html standard, che avrebbe anche potuto essere impostato da codice con element.setAttribute. Angular Elements è incluso nel package @angular/elements, ed espone la funzione createCustomElement(), che può essere usata appunto per creare un customElement da una classe Angular.

Negli elementi custom √® possibile¬†inserire “reactions” come le funzioni callback, attributi, propriet√†, poi richiamabili semplicemente:

<loading-spinner 
  [mode]="mode" [attr.mode]="mode" 
  (modeChange)="doSomething($event)"
  [value]="progress"> 
</loading-spinner>

Caricamento dinamico

Di fatto possiamo considerare Angular Elements¬†come Custom Elements “on steroids”, disegnati¬†appunto¬†per essere portabili. Ma c’√® da dire comunque che per ora gli AE sono utilizzabili solo all’interno di Applicazioni Angular. Questo limite dovrebbe¬†venir meno a partire da Angular 7. Nonostante questa incoerenza, gli Elements sono gi√† utili soprattutto per il contenuto HTML¬†caricato dinamicamente.

HTML content is fetched dynamically from a backend service.
Il contenuto HTML è caricato dinamicamente da un servizio back-end

Che significa? Beh, immaginiamo¬†di voler caricare contenuto¬†da un CMS dentro la propria app Angular: di per s√© non sarebbe un problema, visto che si tratta di comunissimo contenuto HTML. Ma se si volesse abilitare i content editor a usare qualcuno dei componenti Angular che avete scritto, come nell’esempio sotto?

<div>
 <p>The following snippet illustrates this concept:</p>
 <myComponent>[...]</myComponent>
</div>

Cercare di incorporarlo¬†nel codice¬†dell’applicazione¬†via propriet√† come innerHTML¬†(sotto) non funzionerebbe, perch√© i template vengono compilati in anticipo, prima che vengano caricati nel DOM.

template: '<div [innerHTML]="content"></div>'

Non importa se la compilazione sia AoT (Ahead of Time) o JiT (Just in Time), perch√© questo indica solo se la compilazione avviene durante lo sviluppo o nel browser, ma comunque avviene prima che la pagina carichi il template nel DOM. La novit√† di Angular Elements √® che grazie a questi create dei componenti nativi, che in sostanza contengono un intero componente Angular, compreso il codice per fare bootstrap di questa sorta di mini¬†app. Quindi, non c’√® bisogno di Angular per interpretare <myComponent>: tutto il codice necessario √® gi√† contenuto nell’elemento, e viene lanciato assieme al DOM.

LINK

Use SPFx with Angular and Angular CLI

Getting started with Angular Elements

Angular Elements ‚ÄĒ A Practical Introduction To Web Components With Angular¬†6

Building a Custom Element Using Angular Elements