Welcher Workflow soll Polymer mit Angular integrieren?


Polymer. Es verspricht, die Entwicklung von UI-Komponentenbibliotheken zu ermöglichen, ohne an einen technischen Stack gebunden zu sein, und sich auf die (zukünftigen) Fähigkeiten des Browsers zu verlassen. Schreiben Sie einfach seine Komponenten und verwenden Sie sie überall wieder, mit der Garantie, keine Nebenwirkungen zu erzeugen. Es ist wünschenswert, nein ? Wenn Sie mit mehreren Webtechnologien arbeiten und einen Katalog generischer UI-Komponenten entwickeln möchten, scheint Polymer eine gute Lösung zu sein.
Wir werden gemeinsam sehen, wie man eine mit Polymer 2.0 geschriebene Komponente in eine Angular-Anwendung integriert.

Präambel: Polymer- und Webkomponenten

Wenn es nur eines zu beachten gäbe:
Polymer != Webkomponenten
Webkomponenten, die erstmals 2011 erschienen, sind ein Satz von 4 Technologien zum Erstellen und Verwenden von Elementen, deren Stil und Code vom Rest der Anwendung gekapselt sind. Diese 4 Technologien basieren auf W3C-Spezifikationen, von denen sich einige bereits im Living Standard-Status befinden.
Im Jahr 2013 wollten Ingenieure bei Google Webkomponenten zugänglich machen, indem sie ein Overlay für diese Technologien erstellten. Ihr Ziel ist es, mit dem Schreiben und Verwenden von Webkomponenten beginnen zu können, ohne warten zu müssen, bis die Spezifikationen vollständig und in genügend Browsern implementiert sind. Dieses Overlay mit dem hübschen Namen Polymer sollte im Verhältnis zur Browserabdeckung leichter werden oder sogar verschwinden.
Diese 4 Technologien sind:

Benutzerdefinierte Elemente

Dies sind JS-APIs zum Definieren Ihrer HTML-Elemente und des zugehörigen Verhaltens. Nach dem Anruf bei CustomElementRegistry.define(), können Sie dann das entsprechende Tag in Ihrem HTML verwenden.
Sie definieren auch die Lebenszyklus-Callbacks des Elements, das Polymer aufnimmt.

Der Schatten-DOM

Dadurch wird es möglich, die HTML-Struktur und den Stil des Elements zu kapseln, ohne dass die Außenwelt unkontrolliert eingreifen kann.
Polymer verwaltet das Shadow DOM für uns, während es uns erlaubt, es zu manipulieren

HTML-Vorlagen

Dieser Techno definiert zwei Elemente. <template>, wodurch Sie nicht gerenderten HTML-Code schreiben können, der in Elemente kopiert wird, die ihn verwenden. das <slot> lässt uns ein Leerzeichen in unsere HTML-Struktur schreiben, wo die untergeordneten Elemente unseres Elements eingefügt werden.

HTML-Importe

Wenn Sie Ihre Webkomponente in ihrer dedizierten .html-Datei geschrieben haben, besteht eine Möglichkeit, sie in Ihrer Anwendung zu verwenden, darin, sie über einen HTML-Import zu importieren:

<link rel="import" href="myfile.html">

Dieser Techno ist umstritten und wird letztlich nicht vom Standard übernommen. Laut Firefox sind die aktuellen und zukünftigen Tools (ES6-Modul) ausreichend und bieten mehr Kontrolle als der HTML-Import.

Polymerzusätze

Abgesehen davon, dass diese 4 Technologien auf allen Browsern funktionieren, finden Sie in der Polymer-Toolbox etwas, das die Entwicklung von Webkomponenten erleichtert:
– Helfer, um die Eigenschaften unserer Komponente zu deklarieren (Standardwert, schreibgeschützt, berechnet, Beobachterfunktion, automatische Deserialisierung)
– Ereignisverwaltung (automatisches An- und Abmelden, Gestenereignisse für mobile Benutzer)
– Datenverwaltung, mit 2-Wege-Datenbindung
– Benutzerdefinierte Elemente, die ngIf und ngFor von Angular entsprechen
– und verschiedene Dienstprogramme wie z. B. ein Entpreller, um zu vermeiden, dass ein Rückruf in einem zu engen Intervall gerufen wird
Zusätzlich zu diesen grundlegenden Funktionalitäten bietet Polymer Lösungen für die Entwicklung vollständiger Anwendungen (Routenverwaltung, Internationalisierung, Offline-Verwaltung), die nicht sehr nützlich sind, da sie bereits von Angular verwaltet werden.

und eckig?

Angular wurde nach Polymer im September 2014 gestartet. Aber im Gegensatz zu Polymer sind Angular-Komponenten keine Webkomponenten. Sie verwenden dafür spezifische Techniken, wie z. B. eine Emulation des Schattendoms (der auch nativ aktiviert werden kann) für die Kapselung des Stils, aber Sie können eine Angular-Komponente nicht in einer anderen Umgebung als Angular verwenden.

Winkel- und Polymerintegration

Um diese Integration zu veranschaulichen, sehen wir zwei Möglichkeiten: eine einfache und schnelle, bequem zum Testen und die andere besser geeignet für eine Produktionsumgebung.
So oder so, Sie brauchen Bower.

Der einfache Weg

In diesem Fall werden die Zollelemente im Zusammenhang mit dem Angular-Projekt lokal entwickelt. Die Elemente werden in die index.html importiert.

  1. Initialisieren Sie Bower im Stammverzeichnis Ihres Projekts mit
$ bower init

Sofortige Anfragen sind nicht interessant, da wir nicht über Bower veröffentlichen. Unsere Nutzung beschränkt sich auf die Verwaltung von Polymer-Abhängigkeiten.

  1. Erstellen Sie immer noch im Stammverzeichnis eine Datei .bowerrc mit diesem Inhalt:
{
  "directory": "src/assets/bower_components/"
}

assets entspricht Ihrem Angular-Assets-Verzeichnis.

  1. in .gitignore, fügen Sie den gleichen Pfad wie die hinzu directory du .bowerrc.

Für das Beispiel verwenden wir Elemente, die vom Polymer-Team entwickelt wurden.

  1. Installieren Sie die Elemente paper-slider et paper-card
$ bower install --save PolymerElements/paper-slider PolymerElements/paper-card
  1. Fügen Sie Ihre Abhängigkeiten in der index.html hinzu.
<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>
  1. Um Ihre neuen Elemente verwenden zu können, müssen Sie Tags autorisieren, die Angular unbekannt sind. In jedem Modul, das Komponenten mit benutzerdefinierten Elementen deklariert, müssen Sie den Wert anwenden CUSTOM_ELEMENTS_SCHEMA zum Grundstück schemas :
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core";
@NgModule({
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}

Und los geht's! Wenn Sie Ihre WebComponents lokal entwickeln möchten, legen Sie sie in einem Ordner abassets. Verwenden Sie kein Polymer-Cli, das alles generiert, was Sie zum Veröffentlichen benötigen, und mit Inhalten in Konflikt gerät bower_components.
In Ihrem HTML, das Ihre WebComponent definiert, können Sie das nach der Installation von Elementen aus Bower abgerufene Polymer importieren:

<link rel="import" href="../bower_components/polymer/polymer.html">

Die richtige Art zu produzieren

Anstatt alle Ihre Komponenten in den Einstiegspunkt Ihrer Anwendung zu laden, importieren Sie sie auf der TypeScript-Seite in Ihre Angular-Komponenten. Diese werden in den Chunk eingebettet, der dem Modul Ihrer Komponente entspricht, was interessant ist, wenn Sie Ihre Module faul laden. Dadurch reduzieren Sie den Ausgabeaufschlag erheblich.
Möglich wird dies durch das Projekt Polymer-Webpack-Loader wodurch Ihre HTML-Elementdefinitionen in ein JS-Bundle umgewandelt werden.
PolymerWebackLoader-Betrieb
Das ist gut, Webpack ist bereits vorhanden und über Angular CLI konfiguriert. Sie können die von der CLI generierte Konfiguration mit Origami (Polymer + Angular) patchen und damit ein Anwendungsbeispiel sehen Starter-Kit.
Seien Sie jedoch vorsichtig, wenn Ihre Elemente Bilder hosten, müssen Sie die Art und Weise ändern, wie sie verwendet werden. Entweder indem Sie die Bilder in den Asset-Ordner von Angular verschieben, sodass die importPath von Polymer entspricht, entweder durch Verweis darauf über eine Variable:

const img = require('./checked.png');

damit das Bild im Paket enthalten ist.

Integration mit Angular-Formularen

Um ein Polymer-Element in eine Angular-Form zu integrieren, müssen Sie sicherstellen, dass sie dieselbe Sprache sprechen!
Verwendung der Direktive ngDefaultControl auf Ihrer Komponente stellen Sie sicher, dass Angular Ereignisse berücksichtigt input von Ihrer Komponente emittiert. Das heißt, wenn Sie den Wert der FormControl Angular wird durch das Polymer-Element aktualisiert, Sie müssen ein Ereignis ausgeben input. Zum Beispiel für ein Textfeld, input kann nach jedem Tastendruck ausgegeben werden.

class DemoElem extends Polymer.Element {
  static get is() { return 'demo-elem'; }
  static get properties() {
    return {
      value: {
        type: String
      }
    };
  }
  notifyChange() {
    this.dispatchEvent(new CustomEvent('input'));
  }
}

Dann ruft Angular den aktuellen Wert über die Eigenschaft ab value des Bauteils.
Wenn Sie eine abgerufene WebComponent verwenden, die nicht ausgibt input, können Sie eine Direktive übergeben, die implementiert wird ControlValueAccessor. Das Angular-Team hat eine ganze Menge davon entwickelt (Sie finden hier), die wir als Vorlage verwenden können, wenn wir nicht finden, wonach wir suchen. Hier können Sie das Komponentenereignis abhören und das Ergebnis interpretieren, bevor Sie es an das Angular-Formular übergeben, und umgekehrt, wenn das Angular-Formular einen Wert für dieses Steuerelement festlegen möchte.
Ein Implementierungsbeispiel finden Sie im Repo von démo.
Normalerweise erfolgt die Validierung eines Steuerelements immer auf der Angular-Seite über die Validators. Angular kann einer WebComponent per Datenbindung mitteilen, dass sie ungültig ist. Es wird von den vom Polymer-Team entwickelten WebComponents verwaltet, die eine Eigenschaft bereitstellen invalid et error-message. In einigen komplexen Fällen möchten Sie möglicherweise die Gültigkeit in der Komponente verwalten (z. B. um eine bessere Kontrolle über die Formatierung zu haben). Um Angular auf die Ungültigkeit dieser Komponente aufmerksam zu machen, anstatt den Validierungscode zu duplizieren, können Sie ein von der Komponente generiertes Ereignis abfangen, um anzuzeigen, dass sich ihr Gültigkeitsstatus geändert hat.

Fazit: Die Zukunft der Webkomponenten mit Angular

Wir haben gesehen, dass die Integration von Polymer 2.0 in Angular den Workflow verkomplizieren könnte (insbesondere wenn es sich um eine Formularsteuerung handelt). Mit Polymer 3.0 werden wir von Bower zu NPM und von HTML Import zu ES6-Modulen wechseln, wodurch der Build-Schritt erforderlich wird. Als Alternative entwickelt Angular Angular Elements, mit denen wir unsere Angular-Komponenten in Webkomponenten exportieren können, die überall verwendet werden können! Daher denke ich, dass es in Zukunft weniger Interesse geben wird, Polymer zusätzlich zu Angular zu verwenden, wenn beide möglichst viel Wiederverwendbarkeit zulassen… Das wird Geschmackssache sein!
Github-Demoprojekt
Thibault Chevrin, JS-Craftsman @JS-Republik