Web Components + Backbone: a Game-Changing Combination
-
Upload
andrew-rota -
Category
Technology
-
view
21.321 -
download
0
Transcript of Web Components + Backbone: a Game-Changing Combination
Web Components + BackboneA Game-Changing Combination
Who Am I?
Andrew RotaJavaScript Engineer,
JavaScript Modularity
By using small libraries –components with a dedicatedpurpose and a small surfacearea – it becomes possible topick and mix, to swap parts ofour front end stack... - Jimmy Breck-McKye, "The State of JavaScript in2015"
Modularity in HTML == DOM Elements
<ul> <li>First Item</li> <li>Second Item</li></ul>
<ol> <li>First Item</li> <li>Second Item</li></ol>
<div class="header"></div>
<header></header>
<div id="nav"></div>
<nav></nav>
Libraries > frameworks?- Jimmy Breck-McKye, "The State of JavaScript in2015"
Libraries > frameworks?- Jimmy Breck-McKye, "The State of JavaScript in2015"
Native functionality > libraries> frameworks.- Me
But creating your own elementsisn't possible...
... until now.
Web Componentsusher in a new era ofweb developmentbased onencapsulated andinteroperable customelements that extendHTML itself. - Polymer Project
Web Components
Web Component Technologies
Custom Elements
HTML Templates
HTML Imports
Shadow DOM
Web Component Technologies
Custom Elements
HTML Templates
HTML Imports
Shadow DOM
Custom Elements
<my‐element>Hello World.</my‐element>
var MyElement = document.registerElement('my‐element', { prototype: Object.create(HTMLElement.prototype)});
Web Component Technologies
Custom Elements
HTML Templates
HTML Imports
Shadow DOM
HTML Templates<template id="my‐template"> <p>Hello World.</p> <!‐‐ This image won't be downloaded on page load ‐‐> <img src="example.jpg" alt="Example"></template>
document.importNode( document.getElementById('my‐template').content, true);
Web Component Technologies
Custom Elements
HTML Templates
HTML Imports
Shadow DOM
HTML Imports<link rel="import" href="/imports/my‐component.html">
Web Component Technologies
Custom Elements
HTML Templates
HTML Imports
Shadow DOM
Browser Shadow DOM
Shadow DOM<div id="my‐element"></div><p>Light DOM.</p>
// Create Shadow Rootvar s = document.getElementById('my‐element').createShadowRoot();// Add Styles and Texts.innerHTML += '<style>p { color: crimson; }</style>';s.innerHTML += '<p>Shadow DOM.</p>';
Shadow DOM.
Light DOM.
<content><div id="my‐element"><p>Hello!</p></div>
var s = document.getElementById('my‐element').createShadowRoot();s.innerHTML += '<p>Shadow DOM Start.</p>';s.innerHTML += '<style>p { color: crimson; }</style>';s.innerHTML += '<content></content>';s.innerHTML += '<p>Shadow DOM End.</p>';
Shadow DOM Start.Hello!
Shadow DOM End.
Web Component Technologies
Custom Elements
HTML Templates
HTML Imports
Shadow DOM
What Web Components Lack...
Application Structure
Server Interface
URL Router
Models/Collections + Events
...We Gain with Backbone
Application Structure
Server Interface
URL Router
Models/Collections + Events
Using WebComponent
Technologies+
Backbone
Backbone + Custom Elementsdocument.registerElement('my‐custom‐element', { prototype: Object.create(HTMLElement.prototype)});
Backbone.View.extend({ tagName: 'my‐custom‐element'});
Backbone + HTML TemplatesBackbone.View.extend({ template: document.importNode( document.getElementById('my‐template').content, true ), render: function() { this.el.innerHTML = this.template; }});
Backbone + HTML Imports<link rel="import" href="my‐custom‐component.html">
Backbone + Shadow DOMBackbone.View.extend({ initialize: function() { this.el.createShadowRoot(); }});
Using WebComponent
Technologies+
Backbone
Using WebComponents
+Backbone
polymer-project.org/docs/elements
x-tags.org
component.kitchen
customelements.io
Backbone View+
Web Component
<paper‐toast>
<paper‐toast> API
<paper‐toast text="Your toast is ready!" duration="5000" autoCloseDisabled opened></paper‐toast>
Element.show();Element.dismiss();Element.toggle();
Element.addEventListener('core‐overlay‐open‐completed', doSomething
Backbone.View.extend({ tagName: 'paper‐toast', attributes: { text: 'Your toast is ready!', autoCloseDisabled: true, duration: '5000', opened: true }, events: { 'core‐overlay‐open‐completed': 'doSomething' }, toggle: function() { this.el.toggle(); }});
<google‐map>
<google‐map> API
<google‐map zoom="10" latitude="42.3581" longitude="‐71.0636"></google‐map>
Element.resize();Element.clear();
Element.addEventListener('google‐map‐ready', doSomething);
Backbone.View.extend({ tagName: 'google‐map', attributes: { latitude: '42.3581', longitude: '‐71.0636', zoom: '10' }, events: { 'google‐map‐ready': 'doSomething' }, resize: function() { this.el.resize(); }});
Backbone.View.extend({ initialize: function() { this.listenTo(this.model, 'change', this.moveMap ); }, tagName: 'google‐map', moveMap: function(model) { this.el.setAttribute('latitude', this.model.get('lat')); this.el.setAttribute('longitude', this.model.get('long')); this.el.setAttribute('zoom', this.model.get('zoom')); }});
Building Web Componentsfor Backbone (or anything else)
├── hello‐world├──── hello‐world.html├──── hello‐world.js└──── bower.json
<template id="my‐template"> Hello, <content></content</template><script src="hello‐world.js
var element = Object.create(HTMLElement.prototype);
element.createdCallback = function() {};
element.attachedCallback = function() {};
element.attributeChangedCallback = function(attr, oldVal, newVal) {}
element.detachedCallback = function() {};
document.registerElement('hello‐world', { prototype: element});
<link rel="import" href="components/hello‐world/hello‐world.html>
<!‐‐ [...] ‐‐>
<hello‐world>I'm a web component</
How It All Fits Together
Application + Components
Application
Component Component Component Component Component
Component Component Component Component Component
Component Component Component Component Component
Application + Components
Application + Components
Application + Components
< X >
< X >
Web Component All the Things??<backboneconf‐app> <backboneconf‐menu></backboneconf‐menu> <backboneconf‐content></backboneconf‐content> <backboneconf‐footer></backboneconf‐footer></backboneconf‐app>
Probably Not (and that's OK)
I don't ever see us going all inon Custom Elements for everypossible thing ... Use nativeelements and controls whenpossible and supplement withcustom elements. - Joshua Peek, Github Programmer
Should I Componentize?Does it encapsulate component-level logic?
Does it take the place of a native element?
Should it be portable?
Is it context independent?
Can the API be represented as attributes, methods, and events?
Small
Open for Extension
Documented
Unit Tested
Accessible
Idempotent
Best Practices
Can I Use???Custom
ElementsHTML
TemplatesHTML
ImportsShadow
DOM
✓ ✓ ✓ ✓
✓ ✓ ✓ ✓
Flag ✓ Flag Flag
X ✓ X X
X X X X
Can I Use???Custom
ElementsHTML
TemplatesHTML
ImportsShadow
DOM
✓ ✓ ✓ ✓
✓ ✓ ✓ ✓
✓ ✓ ✓ ✓
✓ ✓ ✓ ✓
✓ ✓ ✓ ✓
webcomponents.js
Towards a Component Driven Web
Thanks!
Resources- WebComponents.org- Web Components: A Tectonic Shift for Web Development by Eric Bidelman- Web Components by Jarrod Overson and Jason Strimpel- Ten Principles for Great General Purpose Web Components
Colophon
This presentation was built with Backbone.js, Shadow DOM, HTMLTemplates, HTML Imports, and the Custom Element <slide‐content>using Web Component Slides.