![]()
Polimero. Promette di consentire lo sviluppo di librerie di componenti dell'interfaccia utente senza essere bloccati in uno stack tecnico, basandosi sulle capacità (future) del browser. Basta scrivere i suoi componenti e riutilizzarli ovunque con la garanzia di non generare effetti collaterali. È auspicabile, no? Se lavori con diverse tecnologie web e desideri sviluppare un catalogo di componenti generici dell'interfaccia utente, Polymer potrebbe sembrare una buona soluzione.
Vedremo insieme come integrare un componente scritto con Polymer 2.0 in un'applicazione Angular.
Preambolo: Componenti polimerici e Web
Se ci fosse solo una cosa da ricordare:
Polimero!= Componenti Web
I componenti Web, apparsi per la prima volta nel 2011, sono un insieme di 4 tecnologie per la creazione e l'utilizzo di elementi il cui stile e codice sono incapsulati dal resto dell'applicazione. Queste 4 tecnologie si basano sulle specifiche del W3C, alcune delle quali sono già in stato di Living Standard.
Nel 2013, gli ingegneri di Google volevano rendere accessibili i componenti Web creando una sovrapposizione a queste tecnologie. Il loro obiettivo è essere in grado di iniziare a scrivere e utilizzare componenti Web senza attendere che le specifiche siano complete e implementate in un numero sufficiente di browser. Questo rivestimento, dolcemente chiamato Polymer, era destinato a diventare più leggero, o addirittura a scomparire, in proporzione alla copertura del browser.
Queste 4 tecnologie sono:
Elementi personalizzati
Queste sono API JS per definire i tuoi elementi HTML e il loro comportamento associato. Dopo la chiamata a CustomElementRegistry.define(), puoi quindi utilizzare il tag corrispondente nel tuo HTML.
Definiscono anche i richiami del ciclo di vita dell'elemento prelevato da Polymer.
L'ombra DOM
Questo è ciò che consentirà di incapsulare la struttura HTML e lo stile dell'elemento, senza che il mondo esterno possa interferire in modo incontrollato.
Polymer gestisce per noi lo Shadow DOM, consentendoci al contempo di manipolarlo
Modelli HTML
Questa techno definisce due elementi. <template>, che ti consente di scrivere HTML non renderizzato che verrà copiato negli elementi che li utilizzano. il <slot> ci permette di scrivere uno spazio nella nostra struttura HTML dove verranno inseriti gli elementi figlio del nostro elemento.
Importazioni HTML
Se hai scritto il tuo componente Web nel suo file .html dedicato, un modo per usarlo nella tua applicazione è importarlo tramite un'importazione HTML:
<link rel="import" href="myfile.html">
Questa techno è controversa e alla fine non sarà adottata dallo standard. Secondo Firefox, gli strumenti presenti e futuri (modulo ES6) sono sufficienti e offrono un controllo maggiore rispetto all'importazione HTML.
Aggiunte di polimeri
Oltre a far funzionare queste 4 tecnologie su tutti i browser, troverai nel toolbox Polymer qualcosa per facilitare lo sviluppo di Web Components:
– Helper per dichiarare le proprietà del nostro componente (valore di default, sola lettura, calcolato, funzione osservatore, deserializzazione automatica)
– Gestione degli eventi (iscrizione e disiscrizione automatiche, eventi gestuali per utenti mobili)
– Gestione dei dati, con data binding a 2 vie
– Elementi personalizzati equivalenti a ngIf e ngFor di Angular
– e varie utilità come un antirimbalzo per evitare di chiamare una richiamata a intervalli troppo ravvicinati
Oltre a queste funzionalità di base, Polymer fornisce soluzioni per lo sviluppo di applicazioni complete (gestione dei percorsi, internazionalizzazione, gestione offline), poco utili in quanto già gestite da Angular.
e angolare?
Angular è iniziato dopo Polymer, nel settembre 2014. Ma a differenza di Polymer, i componenti Angular non sono componenti Web. Usano tecniche specifiche per questi, come un'emulazione dello shadow dom (attivabile anche nativamente) per l'incapsulamento dello stile, ma non è possibile utilizzare un componente Angular in un ambiente diverso da Angular.
Integrazione angolare e polimerica
Per illustrare questa integrazione, vedremo due modi: uno semplice e veloce, conveniente per i test, e l'altro più adatto per un ambiente di produzione.
In ogni caso, avrai bisogno di Bower.
Il modo più semplice
In questo caso, gli elementi personalizzati verranno sviluppati localmente, relativi al progetto Angular. Gli elementi vengono importati in index.html.
- Alla radice del tuo progetto, inizializza bower con
$ bower init
Le richieste rapide non sono interessanti perché non pubblicheremo tramite bower. Il nostro utilizzo sarà limitato alla gestione delle dipendenze Polymer.
- Sempre alla radice, crea un file
.bowerrccon questo contenuto:
{
"directory": "src/assets/bower_components/"
}
Où assets corrisponde alla directory delle risorse angolari.
- in
.gitignore, aggiungi lo stesso percorso didirectorydu.bowerrc.
Per l'esempio, utilizzeremo elementi sviluppati dal team Polymer.
- Installa gli articoli
paper-slideretpaper-card
$ bower install --save PolymerElements/paper-slider PolymerElements/paper-card
- Aggiungi le tue dipendenze in index.html.
<head> <link rel="import" href="assets/bower_components/paper-card/paper-card.html"> <link rel="import" href="assets/bower_components/paper-slider/paper-slider.html"> </head> <body> <app-root></app-root> </body>
- Per poter utilizzare i tuoi nuovi elementi, devi autorizzare i tag sconosciuti ad Angular. In ogni modulo che dichiara i componenti utilizzando elementi personalizzati, è necessario applicare il valore
CUSTOM_ELEMENTS_SCHEMAalla proprietàschemas:
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core";
@NgModule({
declarations: [AppComponent],
bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
Ed ecco qua! Se vuoi sviluppare i tuoi WebComponent in locale, mettili in una cartellaassets. Non utilizzare polimero-cli che genererà tutto ciò di cui hai bisogno per pubblicare e entrerà in conflitto con i contenuti bower_components.
Nel tuo HTML che definisce il tuo WebComponent, sarai in grado di importare il Polymer recuperato dopo aver installato gli elementi da bower:
<link rel="import" href="../bower_components/polymer/polymer.html">
Il modo giusto di produrre
Invece di caricare tutti i tuoi componenti nel punto di ingresso della tua applicazione, li importerai nei tuoi componenti Angular sul lato TypeScript. Questi saranno incorporati nel blocco corrispondente al modulo del tuo componente, il che è interessante quando carichi pigri i tuoi moduli. Pertanto, riduci notevolmente la carica iniziale.
Questo è possibile grazie al progetto Caricatore Webpack in polimero che trasformerà le definizioni degli elementi HTML in un bundle JS.

Va bene, Webpack è già presente e configurato tramite Angular CLI. Puoi patchare la configurazione generata dalla CLI usando Origami (Polymer + Angular) e vedere un esempio di utilizzo con questo kit di partenza.
Fai attenzione però, se i tuoi elementi ospitano immagini, dovrai cambiare il modo in cui vengono utilizzati. O spostando le immagini nella cartella delle risorse di Angular in modo che il file importPath di Polymer corrisponde, sia facendo riferimento ad esso tramite una variabile:
const img = require('./checked.png');
in modo che l'immagine sia inclusa nel pacchetto.
Integrazione con forme angolari
Per integrare un elemento Polymer in una forma angolare, devi assicurarti che parlino la stessa lingua!
Utilizzando la direttiva ngDefaultControl sul tuo componente, assicurati che Angular tenga conto degli eventi input emesso dal tuo componente. Cioè, quando vuoi il valore del FormControl Angular viene aggiornato dall'elemento Polymer, dovrai emettere un evento input. Ad esempio per un campo di testo, input può essere emesso dopo ogni battitura.
class DemoElem extends Polymer.Element {
static get is() { return 'demo-elem'; }
static get properties() {
return {
value: {
type: String
}
};
}
notifyChange() {
this.dispatchEvent(new CustomEvent('input'));
}
}
Quindi Angular recupererà il valore corrente tramite la proprietà value del componente.
Se stai utilizzando un WebComponent recuperato che non emette input, puoi passare attraverso una direttiva che verrà implementata ControlValueAccessor. Il team di Angular ha sviluppato una buona sfilza di loro (qui) che possiamo usare come modello se non troviamo quello che stiamo cercando. Qui è dove puoi ascoltare l'evento del componente e interpretare il risultato prima di passarlo al form Angular e viceversa quando il form Angular vuole impostare un valore per quel controllo.
Puoi trovare un esempio di implementazione nel repository di démo.
Normalmente la validazione di un controllo avviene sempre sul lato Angular, tramite il Validators. Angular può dire a un WebComponent che non è valido tramite l'associazione dati. È gestito dai WebComponents sviluppati dal team Polymer che fornisce una proprietà invalid et error-message. In alcuni casi complessi, potresti voler gestire la validità nel componente (per avere un migliore controllo sulla formattazione, ad esempio). Per rendere Angular consapevole dell'invalidità di questo componente, invece di duplicare il codice di convalida, puoi catturare un evento generato dal componente per indicare che il suo stato di validità è cambiato.
Conclusione: il futuro dei componenti Web con Angular
Abbiamo visto che l'integrazione di Polymer 2.0 in Angular potrebbe complicare il flusso di lavoro (soprattutto se si tratta di un controllo di modulo). Con Polymer 3.0, passeremo da Bower a NPM e da HTML Import a moduli ES6, rendendo necessaria la fase di costruzione. In alternativa, Angular sta sviluppando Angular Elements, che ci consentirà di esportare i nostri componenti Angular in componenti Web che possono essere utilizzati ovunque! In futuro, credo quindi che ci sarà meno interesse nell'utilizzare Polymer oltre ad Angular, se entrambi consentiranno altrettanta riutilizzabilità… Sarà una questione di gusti!
Progetto demo Github
Thibalt Chevrin, JS-Craftsman @JS-Repubblica
