SlideShare una empresa de Scribd logo
1 de 44
Descargar para leer sin conexión
PENSANDO EM
COMPONENTES: UM
PARADIGMA NOVO PARA
WEB UIS
Oliver Häger
1. Introdução
Uma (ultra-)breve História do Tempo
Introdução
Introdução
<form name="person-editor" >
<h2>Person Editor </h2>
<label for="firstName" >First Name</label>
<input id="firstName" class="form-control" type="text"
onchange="changed(event)"/>
<label for="lastName">Last Name</label>
<input id="lastName" class="form-control" type="text"
onchange="changed(event)"/>
<!-- ... -->
<button type="button" class="btn btn-success" onclick="save
(event)">Save</button>
</form>
personeditor.html
VanillaJS
var httpRequest = new XMLHttpRequest() ;
var person = {} ;
function changed(event){
person[event. target.id] = event.target.value;
}
function save(){
httpRequest.onreadystatechange = function(){/* ... */} ;
httpRequest. open("POST", "http://www.neolithic.com/person" );
httpRequest. setRequestHeader ('Content-Type' , 'application/json' );
httpRequest. send( JSON.stringify(person) );
}
personeditor.js
VanillaJS
<head>
<script src="js/lib/jquery.js" ></script>
<script src="js/person.editor.plugin.js" ></script>
</head>
<body>
<div id="person-editor" ></div>
<script>
(function(){
function save(data){
// ... send to server
}
$('#person-editor' ).personEditor (save);
})();
</script>
</body>
personeditor.html
jQueryPlugin
function PersonEditor(saveCallback){
var _personData = {};
this.render = function(target){
var form = document.createElement('form');
// create elements here ...
saveButton.addEventListener('click', function(event){
saveCallback(_personData);
});
form.appendChild(inputFirstName);
form.appendChild(inputLastName);
form.appendChild(saveButton);
target.appendChild(form);
}
}
(function($){
$.fn.personEditor = function(saveCallback){
this.each( function() {
var editor = new PersonEditor(saveCallback);
editor.render(this);
});
};
})(jQuery);
personeditor.plugin.js
jQueryPlugin
AngularJS
<form name="person-editor" ng-controller ="personeditorController" >
<h2>Person Editor </h2>
<label for="firstName" >First Name</label>
<input id="firstName" class="form-control" type="text" ng-model="
person.firstName" />
<label for="lastName">Last Name</label>
<input id="lastName" class="form-control" type="text" ng-model="
person.lastName" />
<!-- ... -->
<button type="button" class="btn btn-success" ng-click="save
($event)">Save</button>
</form>
personeditor.html
app.controller("personeditorController" , function($scope, $http){
$scope.person = {};
$scope.save = function(event){
var req = {
method: 'POST',
url: 'http://example.com/api/v1/person' ,
headers: {
'Content-Type' : 'application/json'
},
data: $scope.person
};
$http(req). then(function(){
// handle response
}, console.error);
}
});
personeditor.controller.js
AngularJS
2. Componentes
O novo paradigma
Componentes
Componentes
Componentes
combinável
reutilizável
Componentes
<div class="container" >
<editor-frame title="Person" onsave="savePerson" >
<person-editor></person-editor>
</editor-frame>
<editor-frame title="Product" onsave="saveProduct" >
<product-editor></product-editor>
</editor-frame>
</div>
AngularDirectives
<h2>{{title}}</h2>
<div class="form-group" ng-transclude ></div>
<button class="btn btn-success" ng-click="requestSave (editorModel )"
>Save</button>
editorframe.html
AngularDirectives
angular.module('app.components.editorframe' , [])
.directive('editorFrame' , function() {
return {
templateUrl : 'components/ng/editorframe.html' ,
transclude: true,
scope : {
title : '@',
onsave : '='
},
controller : function($scope){
$scope. editorModel = {};
this.updateModel = function(model){
$scope. editorModel = model;
};
$scope.requestSave = function(editorModel) {
$scope. onsave(editorModel) ;
};
}
};
});
editorframe-component.js
AngularDirectives
<div class="row">
<div class="col-lg-6 col-sm-6" >
<label> First Name</label>
<input class="form-control" type="text" ng-change="changed()"
ng-model="person.firstName" />
</div>
<div class="col-lg-6 col-sm-6" >
<label> Last Name</label>
<input class="form-control" type="text" ng-change="changed()"
ng-model="person.lastName" />
</div>
<div class="col-lg-6 col-sm-6" >
<label> E-Mail</label>
<input class="form-control" type="email" ng-change="changed()"
ng-model="person.email" />
</div>
</div>
person-editor-component.html
AngularDirectives
angular.module('app.components.personeditor' , ['app.components.
editorframe' ])
.directive('personEditor' , function($rootScope) {
return {
require : "^editorFrame" ,
restrict : "AE",
scope : {
} ,
templateUrl : 'components/ng/person-editor-directive.html' ,
link : function($scope, element, attrs, frameCtrl)
{
$scope. changed = function(){
frameCtrl. updateModel ($scope.person);
}
}
};
});
person-editor-component.js
AngularDirectives
Bibliotéca para View
Performático
Sem dependências
Facebook (e Instagram)
ReactJS
Mostrar custom elementvar ReactApp = React. createClass ({
saveCustomer : function(customer) { /* ... */ },
saveProduct : function(product){ /* ... */ },
render: function () {
return (
<div>
<EditorFrame title="Customer Editor" onSave={this.saveCustomer }>
<CustomerEditor/>
</EditorFrame>
<EditorFrame title="Product Editor" onSave={this.saveProduct }>
<ProductEditor/>
</EditorFrame>
</div>
)
}
})
react-app.jsx
ReactJS
Mostrar custom elementvar EditorFrame = React.createClass(
{
propTypes: {
title: React.PropTypes.string.isRequired,
onSave: React.PropTypes.func.isRequired
},
getInitialState : function(){ return {data : {}}; },
change : function(data){ this.state.data = data; },
onSave: function (event) { this.props.onSave(this.state.data); },
render: function () {
// intercept the change callback
this.props.children.props.onChange = this.change;
return (
<div className="panel">
<h3 className="panel-title">{this.props.title}</h3>
<div className="panel-body">
{this.props.children}
<hr/>
<buttonclassName="btn" onClick={this.onSave}>Save</button>
</div>
</div>
)
}
}
);
editor-frame.jsx
ReactJS
Mostrar custom element
var CustomerEditor = React.createClass({
PropTypes: {
onChange : React.PropTypes.func.isRequired
},
getInitialState : function(){ return {data: {}}; },
editorDataChanged: function (event) {
this.state.data[event.target.name] = event.target.value;
this.props.onChange(this.state.data); // propagate data model
},
render: function () {
return (
<div>
<div className="form-group">
<input name="name" className="form-control" type="text"
onChange={this.editorDataChanged}/>
</div>
<div className="form-group">
<input name="email" className="form-control" type="text"
onChange={this.editorDataChanged}/>
</div>
</div>
)
}
});
customer-editor.jsx
ReactJS
Bibliotéca para View
Criado em cima da especificação
Web Components
Google
Catálogo de componentes tipo
Material Design
Polymer
Mostrar custom element
<section data-route= "editor">
<paper-material elevation="1">
<editor-frame title="Person Editor" >
<editor-content-person/>
</editor-frame>
</paper-material>
<paper-material elevation="1">
<editor-frame title="Address Editor" >
<editor-content-address/>
</editor-frame>
</paper-material>
</section>
index.html
Polymer
Mostrar custom element
<link rel="import" href="/bower_components/paper-button/paper-button.html" >
<link rel="import" href="../common/message-dialog.html" >
<dom-module id="editor-frame" >
<style>
:host {
display: block;
}
.button {
margin-top: 1em;
}
@media (max-width: 600px) {
h1.paper-font-display1 {
font-size: 24px;
}
}
</style>
<template>
<!-- part 2 -->
</template>
<script>
<!-- part 3 -->
</script>
</dom-module>
editor-frame.html (1/3)
Polymer
Mostrar custom element<link rel="import" href="/bower_components/paper-button/paper-button.html" >
<link rel="import" href="../common/message-dialog.html" >
<dom-module id="editor-frame" >
<style>
<!-- part 1 -->
</style>
<template>
<h1 class="paper-font-display1" ><span>{{title}}</span></h1>
<div id="content">
<content></content>
</div>
<paper-button class="button" on-click="save" raised>Save</paper-button>
<message-dialog id="dialog" title="Saved Data" message="[[editorData]]"
></message-dialog>
</template>
<script>
<!-- part 3 -->
</script>
</dom-module>
editor-frame.html (2/3)
Polymer
Mostrar custom element<script>
(function () {
Polymer({
is: 'editor-frame' ,
properties: {
editorData: String,
title: {
type: String,
notify: true
}
},
ready: function() {
this.addEventListener ('changed-model' , this.updateModel );
},
updateModel : function(event){
this.editorData = JSON.stringify(event.detail.model);
},
save: function () {
this.$.dialog.open();
}
});
})();
</script>
editor-frame.html (3/3)
Polymer
Mostrar custom element<link rel="import" href="/bower_components/paper-input/paper-input.html" >
<link rel="import" href="editor-content-behaviour.html" >
<dom-module id="editor-content-person" >
<style>
<!-- encapsulated style -->
</style>
<template>
<paper-input class="width-50" name="firstName" label="First Name" on-
change="handleChange" ></paper-input>
<paper-input class="width-50" name="lastName" label="Last Name" on-
change="handleChange" ></paper-input>
</template>
<script>
(function () {
"use strict" ;
Polymer({
is: 'editor-content-person' ,
behaviors : [EditorContentBehavior ]
});
})();
</script>
</dom-module>
editor-content-person.html
Polymer
Mostrar custom element
<script>
EditorContentBehavior = {
properties: {
model : {
type: Object,
value : function () { return {}; } // not shared among instances
}
},
handleChange : function(e){
this.model[e.target.name] = e.target.value;
this.fire('changed-model' , {model : this.model});
}
};
</script>
editor-content-behavior.html
Polymer
3. Componentização
Novos mundos
Componentização
Encapsulamento
DOM
CSS
Javascript
Lifecycle
Virtual DOM
Shadow (Shady) DOM
Scoped Styles
Dados Compartilhados
Instâncias
Pensar em componentes
Fluxo de dados
Arquitetura
Desafios
Reusabilidade
Manutenibilidade
Robustez
Produtividade
Ganhos
Crescimento descontrolado
Black Box
Desenvolvimento Inicial
Riscos
3. Outlook
The next big thing?
Specificação W3C
Conjunto de 4 Sub-Specificações
Templates
Imports
Custom Elements
Shadow DOM
WebComponents
#document-fragment
<my-awesome-element/>
<link rel=”import”/>
<template/>
WebComponents
Templates
Imports
Custom Elements
Shadow DOM
Angular2.0
<html>
<head>
<title>Angular 2 Quickstart </title>
<script src="https://github.jspm.io/jmcriffey/bower-traceur-runtime@0.0.87
/traceur-runtime.js" ></script>
<script src="https://jspm.io/system@0.16.js" ></script>
<script src="https://code.angularjs.org/2.0.0-alpha.28/angular2.dev.js"
></script>
</head>
<body>
<!-- The app component -->
<my-app></my-app>
<script> System.import( 'app');</script>
</body>
</html>
Angular2.0
@Component({
selector: 'my-app'
})
@View({
template: '<h1>Hello {{ name }}</h1>'
})
// Component controller
class MyAppComponent {
name: string;
constructor() {
this.name = 'Alice';
}
}
bootstrap(MyAppComponent) ;
AuraJS
Aurelia
FlightJS
MithrilJS
SkateJS
...
Outros
oliver@devbutze.com
oliver.hager@dextra-sw.com
https://br.linkedin.com/in/oliverhager
Thnx!
Questions!

Más contenido relacionado

La actualidad más candente

Your Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages SuckYour Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages Suck
Anthony Montalbano
 
Javascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & TricksJavascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & Tricks
Hjörtur Hilmarsson
 

La actualidad más candente (20)

Django Bogotá. CBV
Django Bogotá. CBVDjango Bogotá. CBV
Django Bogotá. CBV
 
Ch9 .Best Practices for Class-Based Views
Ch9 .Best Practices  for  Class-Based ViewsCh9 .Best Practices  for  Class-Based Views
Ch9 .Best Practices for Class-Based Views
 
Angular js
Angular jsAngular js
Angular js
 
Jsf lab
Jsf labJsf lab
Jsf lab
 
J Query (Complete Course) by Muhammad Ehtisham Siddiqui
J Query (Complete Course) by Muhammad Ehtisham SiddiquiJ Query (Complete Course) by Muhammad Ehtisham Siddiqui
J Query (Complete Course) by Muhammad Ehtisham Siddiqui
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & Witchery
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
 
AngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
AngularJs Superheroic JavaScript MVW Framework Services by Miracle StudiosAngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
AngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
 
lect4
lect4lect4
lect4
 
Stole16
Stole16Stole16
Stole16
 
22 j query1
22 j query122 j query1
22 j query1
 
Your Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages SuckYour Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages Suck
 
Angular Js Get Started - Complete Course
Angular Js Get Started - Complete CourseAngular Js Get Started - Complete Course
Angular Js Get Started - Complete Course
 
Django class based views for beginners
Django class based views for beginnersDjango class based views for beginners
Django class based views for beginners
 
AngularJS: an introduction
AngularJS: an introductionAngularJS: an introduction
AngularJS: an introduction
 
Neuerungen in JavaServer Faces 2.0
Neuerungen in JavaServer Faces 2.0Neuerungen in JavaServer Faces 2.0
Neuerungen in JavaServer Faces 2.0
 
Javascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & TricksJavascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & Tricks
 
Devoxx 2014-webComponents
Devoxx 2014-webComponentsDevoxx 2014-webComponents
Devoxx 2014-webComponents
 
Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorial
 
MVC and Razor - Doc. v1.2
MVC and Razor - Doc. v1.2MVC and Razor - Doc. v1.2
MVC and Razor - Doc. v1.2
 

Similar a QCon 2015 - Thinking in components: A new paradigm for Web UI

HTML5 and the dawn of rich mobile web applications pt 2
HTML5 and the dawn of rich mobile web applications pt 2HTML5 and the dawn of rich mobile web applications pt 2
HTML5 and the dawn of rich mobile web applications pt 2
James Pearce
 
Index of jquery template 2 Minuteman Summer Web Dev.
Index of jquery template 2 Minuteman Summer Web Dev.Index of jquery template 2 Minuteman Summer Web Dev.
Index of jquery template 2 Minuteman Summer Web Dev.
Daniel Downs
 
Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)
Joao Lucas Santana
 
Angular js quickstart
Angular js quickstartAngular js quickstart
Angular js quickstart
LinkMe Srl
 
Private slideshow
Private slideshowPrivate slideshow
Private slideshow
sblackman
 
Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2
RORLAB
 

Similar a QCon 2015 - Thinking in components: A new paradigm for Web UI (20)

Vaadin Components @ Angular U
Vaadin Components @ Angular UVaadin Components @ Angular U
Vaadin Components @ Angular U
 
Introduction to Html5
Introduction to Html5Introduction to Html5
Introduction to Html5
 
HTML5 and the dawn of rich mobile web applications pt 2
HTML5 and the dawn of rich mobile web applications pt 2HTML5 and the dawn of rich mobile web applications pt 2
HTML5 and the dawn of rich mobile web applications pt 2
 
Enjoy the vue.js
Enjoy the vue.jsEnjoy the vue.js
Enjoy the vue.js
 
Index of jquery template 2 Minuteman Summer Web Dev.
Index of jquery template 2 Minuteman Summer Web Dev.Index of jquery template 2 Minuteman Summer Web Dev.
Index of jquery template 2 Minuteman Summer Web Dev.
 
course js day 3
course js day 3course js day 3
course js day 3
 
Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)
 
Angular js quickstart
Angular js quickstartAngular js quickstart
Angular js quickstart
 
JQuery Mobile UI
JQuery Mobile UIJQuery Mobile UI
JQuery Mobile UI
 
`From Prototype to Drupal` by Andrew Ivasiv
`From Prototype to Drupal` by Andrew Ivasiv`From Prototype to Drupal` by Andrew Ivasiv
`From Prototype to Drupal` by Andrew Ivasiv
 
2.java script dom
2.java script  dom2.java script  dom
2.java script dom
 
Private slideshow
Private slideshowPrivate slideshow
Private slideshow
 
How to Create A Magento Adminhtml Controller in Magento Extension
How to Create A Magento Adminhtml Controller in Magento ExtensionHow to Create A Magento Adminhtml Controller in Magento Extension
How to Create A Magento Adminhtml Controller in Magento Extension
 
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
 
jQuery Mobile - Desenvolvimento para dispositivos móveis
jQuery Mobile - Desenvolvimento para dispositivos móveisjQuery Mobile - Desenvolvimento para dispositivos móveis
jQuery Mobile - Desenvolvimento para dispositivos móveis
 
Jquery tutorial
Jquery tutorialJquery tutorial
Jquery tutorial
 
HTML5 New and Improved
HTML5   New and ImprovedHTML5   New and Improved
HTML5 New and Improved
 
Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2
 
Intro to Jinja2 Templates - San Francisco Flask Meetup
Intro to Jinja2 Templates - San Francisco Flask MeetupIntro to Jinja2 Templates - San Francisco Flask Meetup
Intro to Jinja2 Templates - San Francisco Flask Meetup
 
Jinja2 Templates - San Francisco Flask Meetup
Jinja2 Templates - San Francisco Flask MeetupJinja2 Templates - San Francisco Flask Meetup
Jinja2 Templates - San Francisco Flask Meetup
 

Último

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Último (20)

Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 

QCon 2015 - Thinking in components: A new paradigm for Web UI

  • 6. <form name="person-editor" > <h2>Person Editor </h2> <label for="firstName" >First Name</label> <input id="firstName" class="form-control" type="text" onchange="changed(event)"/> <label for="lastName">Last Name</label> <input id="lastName" class="form-control" type="text" onchange="changed(event)"/> <!-- ... --> <button type="button" class="btn btn-success" onclick="save (event)">Save</button> </form> personeditor.html VanillaJS
  • 7. var httpRequest = new XMLHttpRequest() ; var person = {} ; function changed(event){ person[event. target.id] = event.target.value; } function save(){ httpRequest.onreadystatechange = function(){/* ... */} ; httpRequest. open("POST", "http://www.neolithic.com/person" ); httpRequest. setRequestHeader ('Content-Type' , 'application/json' ); httpRequest. send( JSON.stringify(person) ); } personeditor.js VanillaJS
  • 8. <head> <script src="js/lib/jquery.js" ></script> <script src="js/person.editor.plugin.js" ></script> </head> <body> <div id="person-editor" ></div> <script> (function(){ function save(data){ // ... send to server } $('#person-editor' ).personEditor (save); })(); </script> </body> personeditor.html jQueryPlugin
  • 9. function PersonEditor(saveCallback){ var _personData = {}; this.render = function(target){ var form = document.createElement('form'); // create elements here ... saveButton.addEventListener('click', function(event){ saveCallback(_personData); }); form.appendChild(inputFirstName); form.appendChild(inputLastName); form.appendChild(saveButton); target.appendChild(form); } } (function($){ $.fn.personEditor = function(saveCallback){ this.each( function() { var editor = new PersonEditor(saveCallback); editor.render(this); }); }; })(jQuery); personeditor.plugin.js jQueryPlugin
  • 10. AngularJS <form name="person-editor" ng-controller ="personeditorController" > <h2>Person Editor </h2> <label for="firstName" >First Name</label> <input id="firstName" class="form-control" type="text" ng-model=" person.firstName" /> <label for="lastName">Last Name</label> <input id="lastName" class="form-control" type="text" ng-model=" person.lastName" /> <!-- ... --> <button type="button" class="btn btn-success" ng-click="save ($event)">Save</button> </form> personeditor.html
  • 11. app.controller("personeditorController" , function($scope, $http){ $scope.person = {}; $scope.save = function(event){ var req = { method: 'POST', url: 'http://example.com/api/v1/person' , headers: { 'Content-Type' : 'application/json' }, data: $scope.person }; $http(req). then(function(){ // handle response }, console.error); } }); personeditor.controller.js AngularJS
  • 17. <div class="container" > <editor-frame title="Person" onsave="savePerson" > <person-editor></person-editor> </editor-frame> <editor-frame title="Product" onsave="saveProduct" > <product-editor></product-editor> </editor-frame> </div> AngularDirectives
  • 18. <h2>{{title}}</h2> <div class="form-group" ng-transclude ></div> <button class="btn btn-success" ng-click="requestSave (editorModel )" >Save</button> editorframe.html AngularDirectives
  • 19. angular.module('app.components.editorframe' , []) .directive('editorFrame' , function() { return { templateUrl : 'components/ng/editorframe.html' , transclude: true, scope : { title : '@', onsave : '=' }, controller : function($scope){ $scope. editorModel = {}; this.updateModel = function(model){ $scope. editorModel = model; }; $scope.requestSave = function(editorModel) { $scope. onsave(editorModel) ; }; } }; }); editorframe-component.js AngularDirectives
  • 20. <div class="row"> <div class="col-lg-6 col-sm-6" > <label> First Name</label> <input class="form-control" type="text" ng-change="changed()" ng-model="person.firstName" /> </div> <div class="col-lg-6 col-sm-6" > <label> Last Name</label> <input class="form-control" type="text" ng-change="changed()" ng-model="person.lastName" /> </div> <div class="col-lg-6 col-sm-6" > <label> E-Mail</label> <input class="form-control" type="email" ng-change="changed()" ng-model="person.email" /> </div> </div> person-editor-component.html AngularDirectives
  • 21. angular.module('app.components.personeditor' , ['app.components. editorframe' ]) .directive('personEditor' , function($rootScope) { return { require : "^editorFrame" , restrict : "AE", scope : { } , templateUrl : 'components/ng/person-editor-directive.html' , link : function($scope, element, attrs, frameCtrl) { $scope. changed = function(){ frameCtrl. updateModel ($scope.person); } } }; }); person-editor-component.js AngularDirectives
  • 22. Bibliotéca para View Performático Sem dependências Facebook (e Instagram) ReactJS
  • 23. Mostrar custom elementvar ReactApp = React. createClass ({ saveCustomer : function(customer) { /* ... */ }, saveProduct : function(product){ /* ... */ }, render: function () { return ( <div> <EditorFrame title="Customer Editor" onSave={this.saveCustomer }> <CustomerEditor/> </EditorFrame> <EditorFrame title="Product Editor" onSave={this.saveProduct }> <ProductEditor/> </EditorFrame> </div> ) } }) react-app.jsx ReactJS
  • 24. Mostrar custom elementvar EditorFrame = React.createClass( { propTypes: { title: React.PropTypes.string.isRequired, onSave: React.PropTypes.func.isRequired }, getInitialState : function(){ return {data : {}}; }, change : function(data){ this.state.data = data; }, onSave: function (event) { this.props.onSave(this.state.data); }, render: function () { // intercept the change callback this.props.children.props.onChange = this.change; return ( <div className="panel"> <h3 className="panel-title">{this.props.title}</h3> <div className="panel-body"> {this.props.children} <hr/> <buttonclassName="btn" onClick={this.onSave}>Save</button> </div> </div> ) } } ); editor-frame.jsx ReactJS
  • 25. Mostrar custom element var CustomerEditor = React.createClass({ PropTypes: { onChange : React.PropTypes.func.isRequired }, getInitialState : function(){ return {data: {}}; }, editorDataChanged: function (event) { this.state.data[event.target.name] = event.target.value; this.props.onChange(this.state.data); // propagate data model }, render: function () { return ( <div> <div className="form-group"> <input name="name" className="form-control" type="text" onChange={this.editorDataChanged}/> </div> <div className="form-group"> <input name="email" className="form-control" type="text" onChange={this.editorDataChanged}/> </div> </div> ) } }); customer-editor.jsx ReactJS
  • 26. Bibliotéca para View Criado em cima da especificação Web Components Google Catálogo de componentes tipo Material Design Polymer
  • 27. Mostrar custom element <section data-route= "editor"> <paper-material elevation="1"> <editor-frame title="Person Editor" > <editor-content-person/> </editor-frame> </paper-material> <paper-material elevation="1"> <editor-frame title="Address Editor" > <editor-content-address/> </editor-frame> </paper-material> </section> index.html Polymer
  • 28. Mostrar custom element <link rel="import" href="/bower_components/paper-button/paper-button.html" > <link rel="import" href="../common/message-dialog.html" > <dom-module id="editor-frame" > <style> :host { display: block; } .button { margin-top: 1em; } @media (max-width: 600px) { h1.paper-font-display1 { font-size: 24px; } } </style> <template> <!-- part 2 --> </template> <script> <!-- part 3 --> </script> </dom-module> editor-frame.html (1/3) Polymer
  • 29. Mostrar custom element<link rel="import" href="/bower_components/paper-button/paper-button.html" > <link rel="import" href="../common/message-dialog.html" > <dom-module id="editor-frame" > <style> <!-- part 1 --> </style> <template> <h1 class="paper-font-display1" ><span>{{title}}</span></h1> <div id="content"> <content></content> </div> <paper-button class="button" on-click="save" raised>Save</paper-button> <message-dialog id="dialog" title="Saved Data" message="[[editorData]]" ></message-dialog> </template> <script> <!-- part 3 --> </script> </dom-module> editor-frame.html (2/3) Polymer
  • 30. Mostrar custom element<script> (function () { Polymer({ is: 'editor-frame' , properties: { editorData: String, title: { type: String, notify: true } }, ready: function() { this.addEventListener ('changed-model' , this.updateModel ); }, updateModel : function(event){ this.editorData = JSON.stringify(event.detail.model); }, save: function () { this.$.dialog.open(); } }); })(); </script> editor-frame.html (3/3) Polymer
  • 31. Mostrar custom element<link rel="import" href="/bower_components/paper-input/paper-input.html" > <link rel="import" href="editor-content-behaviour.html" > <dom-module id="editor-content-person" > <style> <!-- encapsulated style --> </style> <template> <paper-input class="width-50" name="firstName" label="First Name" on- change="handleChange" ></paper-input> <paper-input class="width-50" name="lastName" label="Last Name" on- change="handleChange" ></paper-input> </template> <script> (function () { "use strict" ; Polymer({ is: 'editor-content-person' , behaviors : [EditorContentBehavior ] }); })(); </script> </dom-module> editor-content-person.html Polymer
  • 32. Mostrar custom element <script> EditorContentBehavior = { properties: { model : { type: Object, value : function () { return {}; } // not shared among instances } }, handleChange : function(e){ this.model[e.target.name] = e.target.value; this.fire('changed-model' , {model : this.model}); } }; </script> editor-content-behavior.html Polymer
  • 35. Pensar em componentes Fluxo de dados Arquitetura Desafios
  • 38. 3. Outlook The next big thing?
  • 39. Specificação W3C Conjunto de 4 Sub-Specificações Templates Imports Custom Elements Shadow DOM WebComponents #document-fragment <my-awesome-element/> <link rel=”import”/> <template/>
  • 41. Angular2.0 <html> <head> <title>Angular 2 Quickstart </title> <script src="https://github.jspm.io/jmcriffey/bower-traceur-runtime@0.0.87 /traceur-runtime.js" ></script> <script src="https://jspm.io/system@0.16.js" ></script> <script src="https://code.angularjs.org/2.0.0-alpha.28/angular2.dev.js" ></script> </head> <body> <!-- The app component --> <my-app></my-app> <script> System.import( 'app');</script> </body> </html>
  • 42. Angular2.0 @Component({ selector: 'my-app' }) @View({ template: '<h1>Hello {{ name }}</h1>' }) // Component controller class MyAppComponent { name: string; constructor() { this.name = 'Alice'; } } bootstrap(MyAppComponent) ;