Thinking in ComponentsWeb Components, Polymer, React.js, Angular.js
Anton Ivanov, Helsinki.js, 28.04.2015
Powerful Language
“Every powerful language has three mechanisms:
● primitive expressions - which represent the simplest entities the language is concerned with
● means of combination, by which compound elements are built from simpler ones, and
● means of abstraction, by which compound elements can be named and manipulated as units”
“Structure and Interpretation of Computer Programs”, The MIT Press, ISBN-10: 0262510871
Web Components
● HTML imports● Custom elements● Shadow DOM● Templates
Set of standards, a bit like DOM. Provides low level mechanisms.
HTML Imports
● #include for HTML● Styles, scripts, markup imported together
<link rel="import" href="breadcrumbs.html">
Custom Elements
● Extend HTML● Standard APIs continue working
var prototype = Object.create(HTMLElement.prototype);
prototype.setPath = function(path) {...};
document.registerElement('comp-breadcrumbs', {
prototype: prototype
});
Shadow DOM
● Hide markup implementation details● Shadow root
prototype.createdCallback = function() {
...
this.createShadowRoot().appendChild(element);
};
Templates
● Inert pieces of markup● No advanced binding, not like Mustache● Styles
<template id="breadcrumbs-template">
<style>
…
</style>
<div class="breadcrumbs"></div>
</template>
Templates
● To activate should be imported
prototype.createdCallback = function() {
var element = document.importNode(template.content, true);
...
this.createShadowRoot().appendChild(element);
};
Demo
● Source ● Viewable in Chrome
Polymer
● Enables support of new standards● Advanced templating, inheritance● Set of ready to extend useful components● Minor differences with the standards
Library built on top of Web Components standards, like jQuery in 2000s.
Advanced Templating
● Loops, conditionals● Data binding
<template id="breadcrumbs-template">
…
<div class="breadcrumbs" on-keypress="{{_onKeypress}}">
<template id="crumbs" repeat="{{crumb, index in crumbs}}">
...
</template>
</div>
</template>
Useful Components
● core-item, core-ajax, core-collapse, etc.● Inherit to use in your component
<polymer-element name="my-element" extends="core-ajax">
Demo
● Source or standards-only source ● Viewable not only in Chrome
React.js
● Components ~ functions● Declarative● Everything is a component● Own tree of components in memory● Clever to re-render only what's needed
Transforms data into 'immutable' HTML via a tree of components. View library not a framework.
Component
● render method● Life cycle hooks● props - immutable state, set as attributes● state – mutable state● Hierarchy of components, data 'flows' from
root
Component
var CrumbSeparator = React.createClass({
render: function() {
return (
<span className="crumb-separator" title={this.props.tooltip}>{this.props.value}</span>
)
}
});
● Declarative, functional-like● JSX for templates
Component
var BreadcrumbsDemo = React.createClass({
...
render: function() {
return (
<div>
<div id="breadcrumb-container">
<Breadcrumbs path={this.state.path} maxEntries="5" onChange={this.onPathChange}/>
</div>
...
</div>
)
● Nesting
Flux
● How data should be fed to component tree● Data flows through one control point
Recommended architecture for React.
Demo
● Source ● Viewable
Angular.js
● Testability● Templates, view updates● Directives● Predefined directives● Components implemented as directives,
not a central feature
MVC framework. Enhances HTML annotated with directives, handles routine tasks.
Testability
angular.module('Components')
.controller('breadcrumbsController', function ($scope) {
…
});
● Dependency injection● Modularity
Templates
<div class="breadcrumbs">
<span ng-class="{'crumb': !pathPart.dots, 'crumb-separator': pathPart.dots}"
ng-click="activatePathPart(pathPart)" ...
ng-repeat-start="pathPart in pathToRender"> {{pathPart.value}}
</span>
<span class="crumb-separator" ng-if="$index < pathToRender.length - 1" ng-repeat-end>></span>
</div>
● Two-way data binding● HTML generation
Directives
● Predefined: ng-app, ng-controller, etc.● Annotating HTML● As classes, attributes, elements
Directives
angular.module('Components')
.directive('compBreadcrumbs', function () {
return {
restrict: 'E',
scope: {
path: '=',
...
},
controller: 'breadcrumbsController',
templateUrl: 'breadcrumbs.tpl.html'
};
});
Controllers
<body ng-app="BreadcrumbsDemo" ng-controller="Path">
...
</body>angular.module('Components')
.controller('Path', function Path($scope, fullPath) {
$scope.reset = function() {
$scope.path = fullPath;
};
...
});
● Augment scope with behavior
Angular 2.0
@Component({selector: 'my-app' })
@Template({inline: '<h1>Hello {{ name }}</h1>' })
class MyAppComponent {
constructor() {
this.name = 'Alice';
}
}
● Simplified● Focus on components● ES6 support
Demo
● Source● Viewable
Summary
● Web Components just low level standards● Polymer like jQuery● If more needed, React or Angular● React philosophy more in line with JS● Angular radically redefines JS
development practices. Good or bad?● Future integration with Web Components● Other options
Attribution● Image of Apple Web site in 1997 from https://www.magicdust.com.au/evolution-apples-website/
● Cloud9 IDE image taken as screenshot from https://c9.io/ (example of a Web app in 2015)
● “School of Athens” fresco by Raphael, Apostolic Palace, Vatican City, fragment from http://en.wikipedia.org/wiki/The_School_of_Athens#/media/File:Sanzio_01.jpg
● “Structure and Interpretation of Computer Programs” book cover image from https://mitpress.mit.edu/sicp/full-text/book/book.html
● Web Components logo from http://webcomponents.org/
● Polymer logo from https://www.polymer-project.org/0.5/
● React.js logo from https://facebook.github.io/react/
● Flux architecture image from https://facebook.github.io/react/docs/flux-overview.html
● “Java EE Design Patterns” book cover image from http://www.wrox.com/WileyCDA/WroxTitle/Professional-Java-EE-Design-Patterns.productCd-111884341X.html
● Angular.js logo from https://angular.io/
● App split into components image from https://facebook.github.io/react/docs/thinking-in-react.html
● Curtains image by eveyD http://eveyd.deviantart.com
● Made with LibreOffice Impress https://www.libreoffice.org/discover/impress/
Top Related