40
Thinking in Components Web Components, Polymer, React.js, Angular.js Anton Ivanov, Helsinki.js, 28.04.2015

Thinking in Components

Embed Size (px)

Citation preview

Thinking in ComponentsWeb Components, Polymer, React.js, Angular.js

Anton Ivanov, Helsinki.js, 28.04.2015

Why?

● Maintainability● Code reuse● Similar to classes, functions● Familiar concept

1997

2015

div soup

A bit of Philosophy

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);

};

Shadow DOM

● Already used by <video> in Chrome

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);

};

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">

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.

Flux

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>&gt;</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'

};

});

Scopes

● Model● Hierarchy● Bound to HTML with special directives

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

More core concepts...

● Services● Factories● Constants

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

Mental Model

● Thinking in components

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

Thank you!

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/