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