mit Polymer und AngularJS 1 - inovex GmbH · PDF fileWeb Components mit Polymer und AngularJS...

Post on 06-Feb-2018

218 views 2 download

Transcript of mit Polymer und AngularJS 1 - inovex GmbH · PDF fileWeb Components mit Polymer und AngularJS...

Web Componentsmit Polymer und AngularJS 1.x

Patrick Hillert, 21. April 2016

+

Patrick HillertM.Sc. (Informatik)

Web-Softwareentwickler

Modern Web

Neue Web APIs + Tools@silentHoo

/silentHoo

/PatrickHillert

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

Agenda

</> Probleme der Webentwicklung

</> Web Components und Polymer

</> Demo: AngularJS trifft auf Web Components

</> Tooling + Roadmap

https://commons.wikimedia.org/wiki/File:Old_timer_structural_worker.jpg“Old-timer, keeping up with the boys…”, licensed under Public Domain. Photo taken by Lewis Hine.

https://dribbble.com/meidenberg/projects/6336-Me-Dark-UI-kit

Designs in 2016 sollten für das Web einfach umzusetzen sein

Mikael Eidenberg@meidenberg

“It’s super-easy with Bootstrap”

Modaler Dialog

http://getbootstrap.com/javascript/#modals

“Just copy this simple html …”

http://getbootstrap.com/javascript/#modals

“... and this little script.”

“Isn’t that easy?”

http://getbootstrap.com/javascript/#modals

https://www.flickr.com/photos/122127718@N08/13579450523/“84 Rusty Color Metal texture - 4”, licensed under CC BY-SA 2.0. Copyright by texturepalace.

Problem #1:Boilerplate-Code

https://www.flickr.com/photos/122127718@N08/13579450523/“84 Rusty Color Metal texture - 4”, licensed under CC BY-SA 2.0. Copyright by texturepalace.

Problem #2:Interne Implementierung-details sind sichtbar

https://www.flickr.com/photos/122127718@N08/13579450523/“84 Rusty Color Metal texture - 4”, licensed under CC BY-SA 2.0. Copyright by texturepalace.

Problem #3:Frontends sind komplex

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

Wird es durch Web Components einfacher?

<google-map latitude="49.0135165" longitude="8.4022463"></google-map>

<google-map latitude="49.0135165" longitude="8.4022463">

<google-map-marker latitude="49.0135165" longitude="8.4022463"> </google-map-marker>

</google-map>

<google-map map="{{map}}" latitude="49.0135165" longitude="8.4022463">

<google-map-marker latitude="49.0135165" longitude="8.4022463"> </google-map-marker>

</google-map>

<google-map-directions map="{{map}}" start-address="Karlsruhe" end-address="München"></google-map-directions>

<google-map map="{{map}}" latitude="49.0135165" longitude="8.4022463">

<google-map-marker latitude="49.0135165" longitude="8.4022463"> </google-map-marker>

</google-map>

<google-map-directions map="{{map}}" start-address="Karlsruhe" end-address="München"></google-map-directions>

http://jsfiddle.net/mprej0j4/67/

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

Sind Komponenten die Lösung?

Teile und Herrsche Komplexität in kleine Häppchen aufteilen

20162006 2009 2013

2

Teile und Herrsche Komplexität in kleine Häppchen aufteilen

20162006 2009 2013

2

Plugins

Teile und Herrsche Komplexität in kleine Häppchen aufteilen

20162006 2009 2013

2

PluginsDirektiven, ...

Teile und Herrsche Komplexität in kleine Häppchen aufteilen

20162006 2009 2013

2

PluginsDirektiven, ...

“Stateful View Components”

Teile und Herrsche Komplexität in kleine Häppchen aufteilen

20162006 2009 2013

2

PluginsDirektiven, ...

“Stateful View Components”

Web Components

Teile und Herrsche Komplexität in kleine Häppchen aufteilen

20162006 2009 2011 2013

2

W3C Standard

Teile und Herrsche Komplexität in kleine Häppchen aufteilen

20162006 2009 2011 2013

2

W3C Standard1.5: “module.component”

Teile und Herrsche Komplexität in kleine Häppchen aufteilen

20162006 2009 2011 2013

2

W3C Standard1.5: “module.component”+ Trennung der Verantwortlichkeit

+ Eine Einheit -> Besser testbar

+ (Wiederverwendbar)

https://www.flickr.com/photos/krossbow/4026537359/“Halloween Palette Background set”, licensed under CC BY 2.0. Copyright by F Delventhal.

“keep it simple”

https://www.flickr.com/photos/krossbow/4026537359/“Halloween Palette Background set”, licensed under CC BY 2.0. Copyright by F Delventhal.

“think local”

“keep it simple”

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

Web Components und Polymer

“Web Components”

Web Components

Custom Elements Shadow DOM HTML Imports HTML Templates

HTML5

W3C Editor’s Draft

W3C Recomm. Track Process Maturity Levels

W3C Working Draft (WD)W3C Candidate Recommendation (CR)W3C Proposed Recommendation (PR)W3C Recommendation (REC)

W3C NoteNo Specification

moved to HTML5

https://www.flickr.com/photos/krossbow/4026537359/“Halloween Palette Background set”, licensed under CC BY 2.0. Copyright by F Delventhal.

“The Polymer library is a lightweight sugaring layer on top of the web components

APIs [...]”https://github.com/Polymer/polymer

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

Browsersupport

Browser-Support (nativ)Frühjahr 2016

seit Version 36+

MOBILE / TABLETDESKTOP

HTML Templates

HTML Imports

Custom Elements

Shadow DOM

*

* Chrome for Android / Android Browser

10+ 10+7+7+

Browser-Support (polyfilled)Frühjahr 2016

Quelle: polymer-project.org

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

Custom Elements

Custom Elements

● Semantische Information

● “Klassen für das Web”

● Wiederverwendbar

<paper-slider pin snaps max="10" step="1" value="5" class="orange"></paper-slider>

Custom Elements

● Semantische Information

● “Klassen für das Web”

● Wiederverwendbar

<paper-slider pin snaps max="10" step="1" value="5" class="orange"></paper-slider>

Neue Browser-API: document.registerElement(‘paper-slider’, /* proto */);

Custom Elements

● Semantische Information

● “Klassen für das Web”

● Wiederverwendbar

<paper-slider pin snaps max="10" step="1" value="5" class="orange"></paper-slider>

Neue Browser-API: document.registerElement(‘paper-slider’, /* proto */);

NATIVERCODE*

*: Wollen wir nicht von Hand schreiben, Polymer übernimmt das für uns!

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

HTML Imports

HTML Imports

<link rel="stylesheet" href=".../css/bootstrap.min.css">

<link rel="stylesheet" href=".../css/bootstrap-theme.min.css">

<script src=".../jquery.min.js"></script>

<script src=".../js/bootstrap.min.js"></script>

<link rel="import" href=".../bootstrap.html">

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

HTML Templates

HTML Templates

● Beschreibt DOM

● Bilder, Skripte bleiben inaktiv bis

clone()

● Leichtgewichtig

<template id="myTemplate"> <div class="profile"> <img src="/profile-pic.jpg"> </div> <script> // ... </script></template>

HTML Templates

<template id="myTemplate"> <div class="profile"> <img src="/profile-pic.jpg"> </div> <script> // ... </script></template>

Aktivierung durch clone() in JavaScript: var t = document.querySelector(‘#myTemplate’);

var clone = document.importNode(t.content, true);

document.body.appendChild(clone);

● Beschreibt DOM

● Bilder, Skripte bleiben inaktiv bis

clone()

● Leichtgewichtig

HTML Templates

<template id="myTemplate"> <div class="profile"> <img src="/profile-pic.jpg"> </div> <script> // ... </script></template>

Aktivierung durch clone() in JavaScript: var t = document.querySelector(‘#myTemplate’);

var clone = document.importNode(t.content, true);

document.body.appendChild(clone);

NATIVERCODE*

● Beschreibt DOM

● Bilder, Skripte bleiben inaktiv bis

clone()

● Leichtgewichtig

*: Wollen wir nicht von Hand schreiben, Polymer übernimmt das für uns!

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

Shadow DOM

Shadow DOMbereits seit Jahren in Browsern integriert, um Komplexität beherrschbar zu machen

<video src="foo.webm" controls></video>

Shadow DOMbereits seit Jahren in Browsern integriert, um Komplexität beherrschbar zu machen

<video src="foo.webm" controls></video>

Shadow DOMbereits seit Jahren in Browsern integriert, um Komplexität beherrschbar zu machen

<video src="foo.webm" controls></video>

Shadow DOMbereits seit Jahren in Browsern integriert, um Komplexität beherrschbar zu machen

<video src="foo.webm" controls></video>

Durch Browsereingefügt

Shadow DOMbereits seit Jahren in Browsern integriert, um Komplexität beherrschbar zu machen

<video src="foo.webm" controls></video>

Durch Browsereingefügt

● Kein Ersatz zu <iframe>

● Kein separater JavaScript-Kontext

● Gekapseltes Styling / Markup

Shadow DOMbereits seit Jahren in Browsern integriert, um Komplexität beherrschbar zu machen

<video src="foo.webm" controls></video>

Durch Browsereingefügt

● Kein Ersatz zu <iframe>

● Kein separater JavaScript-Kontext

● Gekapseltes Styling / Markup

Neue Browser-API: var shadow = document.querySelector(‘#myId’).createShadowRoot();

var template = document.querySelector(‘#myIdTemplate’);

var clone = document.importNode(template.content, true);

shadow.appendChild(clone);

Shadow DOMbereits seit Jahren in Browsern integriert, um Komplexität beherrschbar zu machen

<video src="foo.webm" controls></video>

Durch Browsereingefügt

● Kein Ersatz zu <iframe>

● Kein separater JavaScript-Kontext

● Gekapseltes Styling / Markup

Neue Browser-API: var shadow = document.querySelector(‘#myId’).createShadowRoot();

var template = document.querySelector(‘#myIdTemplate’);

var clone = document.importNode(template.content, true);

shadow.appendChild(clone);

NATIVERCODE*

*: Wollen wir nicht von Hand schreiben, Polymer übernimmt das für uns!

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

“Putting it all together”

Poly

mer

Shad

ow D

OM /

Shad

y DO

M HTML-Template

“Putting it all together”

HTML-Markup

Scripts + Styling

Public Attributes (Markup)

+Public Methods

(JavaScript)

custom-element

HTML-Import

<paper-tabs selected="0">

<paper-tab>ITEM ONE</paper-tab>

<paper-tab>ITEM TWO</paper-tab>

<paper-tab>ITEM THREE</paper-tab>

</paper-tabs>

“Putting it all together”

<paper-tabs selected="0">

<paper-tab>ITEM ONE</paper-tab>

<paper-tab>ITEM TWO</paper-tab>

<paper-tab>ITEM THREE</paper-tab>

</paper-tabs>

“Putting it all together”

<paper-tabs selected="0">

<paper-tab>ITEM ONE</paper-tab>

<paper-tab>ITEM TWO</paper-tab>

<paper-tab>ITEM THREE</paper-tab>

</paper-tabs>

“Ripple-Effekt” +Animationen

Einfacher Markup,kein Boilerplate-Code

“Putting it all together”

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

Demo

http://todomvc.com/examples/angularjs

Demo

Nur 3 Use Cases

● Hinzufügen

Nur 3 Use Cases

● Hinzufügen

● Bearbeiten

Nur 3 Use Cases

● Hinzufügen

● Bearbeiten

● Abhaken

Los geht’s!

$ git clone git@github.com:tastejs/todomvc.git

copy examples/angularjs → examples/angularjs-polymer

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

#1: Fälligkeitsdatum hinzufügen

Download + Import

https://customelements.io/vaadin/vaadin-date-picker/

$ bower install --save vaadin-date-picker

<link rel=”import” href=”bow.../vaadin-date-picker.html”>

<vaadin-date-picker>

Ausgangsbasis

<html> <head> <!-- ... --> </head>

<body ng-app=”todomvc”> <form> <input placeholder=”What needs to be done?” ng-model=”newTodo” ng-disabled=”saving” autofocus> </form> </body></html>

/examples/angularjs-polymer/index.html

https://github.com/silentHoo/todomvc-ngpoly

<html> <head> <link rel=”import” href=”bower_components/vaadin-date-picker/vaadin-date-picker.html”> </head>

<body ng-app=”todomvc”> <form> <input placeholder=”What needs to be done?” ng-model=”newTodo” ng-disabled=”saving” autofocus> <vaadin-date-picker ng-model=”newDeadline” value=”2016-04-21” label=”Deadline”> </form> </body></html>

Änderungen/examples/angularjs-polymer/index.html

angular.module(‘todomvc’) .controller(‘TodoCtrl’, function() { // ... $scope.newDeadline = new Date(); });

TodoCtrl

https://github.com/silentHoo/todomvc-ngpoly

Und wie sieht die UI aus?Flexbox

https://github.com/silentHoo/todomvc-ngpoly

Problem #1: ngModel funktioniert nicht

● Komponente sendet Event “value-changed”

● Nur mit Eventlistener ist Zugriff möglich:

● Lösung: Direktive, die diese Art der Events handelt und im Model setzt.

addEventListener(‘value-changed’, function() { … })

https://github.com/silentHoo/todomvc-ngpoly

Lösung: Direktive “polyBind”/examples/angularjs-polymer/js/directives/polybind.js

https://github.com/silentHoo/todomvc-ngpoly

<html> <head> <link rel=”import” href=”bower_components/vaadin-date-picker/vaadin-date-picker.html”> </head>

<body ng-app=”todomvc”> <form ng-keypress=”$event.which === 13 && addTodo()”> <input placeholder=”What needs to be done?” ng-model=”newTodo” ng-disabled=”saving” autofocus> <vaadin-date-picker ... poly-bind=”{{ { event: ‘value-changed’, modelValue: ‘value’ } }}” label=”Deadline”> </form> </body></html>

Änderungen: “polyBind”/examples/angularjs-polymer/index.html

angular.module(‘todomvc’) .controller(‘TodoCtrl’, function() { // ... $scope.addTodo = function() { var newTodo = { title: $scope.newTodo.trim(), deadline: moment($scope.newDeadline).toDate(), completed: false }; }; });

TodoCtrl

momentjs

https://github.com/silentHoo/todomvc-ngpoly

Fälligkeit initial auf “heute” setzen

<html> <head> <link rel=”import” href=”bower_components/vaadin-date-picker/vaadin-date-picker.html”> </head>

<body ng-app=”todomvc”> <form ng-keypress=”$event.which === 13 && addTodo()”> <input placeholder=”What needs to be done?” ng-model=”newTodo” ng-disabled=”saving” autofocus> <vaadin-date-picker ... value=”{{ ::newDeadline | amDateFormat: ‘YYYY-MM-DD’ }}” label=”Deadline”> </form> </body></html>

/examples/angularjs-polymer/index.html

https://github.com/silentHoo/todomvc-ngpoly

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

#2: Fälligkeit in Liste anzeigen

<li ng-repeat=”todo in todos” …> <div> <input type=”checkbox” ng-model=”todo.completed” ng-change=”toggleCompleted(todo)”> <label ng-dblclick=”editTodo(todo)”>{{todo.title}}</label> </div> </li>

/examples/angularjs-polymer/index.html

<li ng-repeat=”todo in todos” …> <div> <input type=”checkbox” ng-model=”todo.completed” ng-change=”toggleCompleted(todo)”> <div> <label ng-dblclick=”editTodo(todo)”>{{todo.title}}</label> <div> <label>{{ todo.deadline | amDateFormat: ‘MM/DD/YYYY’ }}</label> </div> </div> </div> </li>

https://github.com/silentHoo/todomvc-ngpoly

UI mit sichtbarer Deadline

https://github.com/silentHoo/todomvc-ngpoly

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

#3: Tooltip um “Created at” Zeitstempel ergänzen

Download + Import

$ bower install --save PolymerElements/paper-tooltip

<link rel=”import” href=”bow.../paper-tooltip.html”>

<paper-tooltip>

https://elements.polymer-project.org/elements/paper-tooltip

Download + Import

$ bower install --save PolymerElements/paper-tooltip

<link rel=”import” href=”bow.../paper-tooltip.html”>

<paper-tooltip>

https://elements.polymer-project.org/elements/paper-tooltip

... <li ng-repeat=”todo in todos … track by $index” …> ... <div> <label ng-dblclick=”editTodo(todo)”>{{todo.title}}</label> <div> <label id=”todo-tooltip-{{$index}}”>{{ todo.deadline | amDateFormat: ‘MM/DD/YYYY’ }}</label> <paper-tooltip for=”todo-tooltip-{{$index}}” position=”left” animation-delay=”0”> Created at {{ todo.createdAt }} </paper-tooltip> </div> </div> ... </li>

Naiver Ansatz/examples/angularjs-polymer/index.html

// ... var newTodo = { // ... createdAt: new Date() };

TodoCtrl

https://github.com/silentHoo/todomvc-ngpoly

... <li ng-repeat=”todo in todos … track by $index” …> ... <div> <label ng-dblclick=”editTodo(todo)”>{{todo.title}}</label> <div> <label id=”todo-tooltip-{{$index}}”>{{ todo.deadline | amDateFormat: ‘MM/DD/YYYY’ }}</label> <paper-tooltip for=”todo-tooltip-{{$index}}” position=”left” animation-delay=”0”> Created at {{ todo.createdAt }} </paper-tooltip> </div> </div> ... </li>

Naiver Ansatz/examples/angularjs-polymer/index.html

// ... var newTodo = { // ... createdAt: new Date() };

TodoCtrl

https://github.com/silentHoo/todomvc-ngpoly

Lösung: ng-attr-*

... <li ng-repeat=”todo in todos … track by $index” …> ... <div> <label ng-dblclick=”editTodo(todo)”>{{todo.title}}</label> <div> <label ng-attr-id=”todo-tooltip-{{$index}}”>{{ todo.deadline | amDateFormat: ‘MM/DD/YYYY’ }}</label> <paper-tooltip ng-attr-for=”todo-tooltip-{{$index}}” position=”left” animation-delay=”0”> Created at {{ todo.createdAt }} </paper-tooltip> </div> </div> ... </li>

/examples/angularjs-polymer/index.html

https://github.com/silentHoo/todomvc-ngpoly

UI um Tooltip erweitert

https://github.com/silentHoo/todomvc-ngpoly

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

#4: Datepicker lokalisieren

Verwenden der Objekt-API

https://vaadin.com/docs/-/part/elements/vaadin-date-picker/vaadin-date-picker-features.html

... <vaadin-date-picker id=”todo-datepicker” ng-model=”newDeadline” value=”2016-04-21” label=”Deadline”>...

/examples/angularjs-polymer/index.html

angular.module(‘todomvc’) .controller(‘TodoCtrl’, function() { $scope.dateFormat = ‘DD.MM.YYYY’;

var datePicker = CustomElementHelper.getInstance(‘#todo-datepicker’); datePicker.i18n.formatDate = function(date) { return moment(date).format($scope.dateFormat); } });

TodoCtrl

Verwenden der Objekt-API

https://github.com/silentHoo/todomvc-ngpoly

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

Live-Demo

Fazit: Abwägen

● Gibt es eine ausreichende Lösung für das Framework?○ Lösung bevorzugen, wenn Sie den Funktionsumfang bietet, den man

benötigt. Bessere Integration in Framework.

● Es gibt keine Lösung für Framework aber eine Komponente?○ Komponente verwenden statt neu entwickeln. Aufwand für

Wrapping/Integration in Framework lohnt sich in jedem Fall.

https://www.flickr.com/photos/hades2k/7520172586/“Blue wall wallpaper”, licensed under CC BY-SA 2.0. Copyright by Hades2k.

Tooling + Roadmap

● CLI-Generatoren

● Web Component Tester (Unit Tests)

Tooling

https://github.com/yeoman/generator-polymer

I. Generatoren

● App-Stub

○ Element- inkl. Test-Stubs

● GitHub-Pages für Dokumentation

basiert auf Polymer-Starter-Kit

Erzeugt statische Doku auf <user.>.github.io

# install yeoman polymer generator

npm install -g generator-polymer

# init your app

yo polymer

# add a reusable element

yo polymer:seed

# publish on github

yo polymer:gh

https://github.com/yeoman/generator-polymer

II. Web Component Tester

Others

LOCAL TESTINGREMOTE TESTING

WCT

Automated Cross-Browser Testing

https://github.com/Polymer/web-component-tester

https://blog.polymer-project.org

Roadmap 2016

2016

Publish Philosophie

Routing

Lazy-loading elementsl10n/i18n

Gute “Community-Elemente” promoten

100% mehr PRs akzeptierenPerformance vorhandener Elemente verbessern

Mehr Feature Opt-InsVererbung bei eigenen “Custom Elements”

Ultimate Polymer CLI

Weitere Ressourcen

Polymer Summit 2015 CodeLab Tutorialshttp://www.code-labs.io/polymer-summit

Web Components “Gold Standard” alias “Best Practices”https://github.com/webcomponents/gold-standard/wiki

Polycastshttps://www.youtube.com/playlist?list=PLOU2XLYxmsII5c3Mgw6fNYCzaWrsM3sMN

Polymer Summit 2015https://www.youtube.com/playlist?list=PLNYkxOF6rcICdISJclfQhj2S8QZGjXV8J

Kontakt

inovex GmbHLudwig-Erhard-Allee 676131 Karlsruhe

Patrick Hillertpatrick.hillert@inovex.de

@silentHoo

/silentHoo

/PatrickHillert

Quellenverzeichnis / RechtlichesDie Quellen finden sich jeweils direkt an der entsprechenden Stelle des zitierten Werkes. / All sources are given appropriate credit at the place of their corresponding place on slide.

Die verwendeten Logos sind Eigentum der jeweiligen Inhaber. / All logos and trademarks are the property of their respective owners. If you are the owner and don’t want to show, please let me know.

Copyright by Last Call Media Inc., Free for Commercial Use, https://www.iconfinder.com/icons/296208/axe_configuration_gear_mining_pick_pickaxe_tool_tools_work_icon#size=128

Copyright by the gnome.org project, licensed under GPL, https://www.iconfinder.com/icons/55596/accept_check_ok_tick_icon#size=64

Copyright by Ionicicons.com, licensed under MIT, https://www.iconfinder.com/icons/211746/flag_outline_icon#size=64