SlideShare a Scribd company logo
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!

More Related Content

What's hot

Django Bogotá. CBV
Django Bogotá. CBVDjango Bogotá. CBV
Django Bogotá. CBV
ctrl-alt-delete
 
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
Willy Liu
 
Angular js
Angular jsAngular js
Angular js
prasaddammalapati
 
Jsf lab
Jsf labJsf lab
Jsf lab
Yu-Ting Chen
 
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
Muhammad Ehtisham Siddiqui
 
Django Admin: Widgetry & Witchery
Django Admin: Widgetry & WitcheryDjango Admin: Widgetry & Witchery
Django Admin: Widgetry & Witchery
Pamela Fox
 
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
EPAM Systems
 
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
Learnimtactics
 
Stole16
Stole16Stole16
Stole16
rworldoffice
 
22 j query1
22 j query122 j query1
22 j query1
Fajar Baskoro
 
Your Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages SuckYour Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages SuckAnthony Montalbano
 
Angular Js Get Started - Complete Course
Angular Js Get Started - Complete CourseAngular Js Get Started - Complete Course
Angular Js Get Started - Complete Course
EPAM Systems
 
Django class based views for beginners
Django class based views for beginnersDjango class based views for beginners
Django class based views for beginners
Spin Lai
 
AngularJS: an introduction
AngularJS: an introductionAngularJS: an introduction
AngularJS: an introduction
Luigi De Russis
 
Neuerungen in JavaServer Faces 2.0
Neuerungen in JavaServer Faces 2.0Neuerungen in JavaServer Faces 2.0
Neuerungen in JavaServer Faces 2.0
gedoplan
 
Javascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & TricksJavascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & TricksHjörtur Hilmarsson
 
Devoxx 2014-webComponents
Devoxx 2014-webComponentsDevoxx 2014-webComponents
Devoxx 2014-webComponents
Cyril Balit
 
Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorial
Claude Tech
 
MVC and Razor - Doc. v1.2
MVC and Razor - Doc. v1.2MVC and Razor - Doc. v1.2
MVC and Razor - Doc. v1.2
Naji El Kotob
 

What's hot (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 to QCon 2015 - Thinking in components: A new paradigm for Web UI

Vaadin Components @ Angular U
Vaadin Components @ Angular UVaadin Components @ Angular U
Vaadin Components @ Angular U
Joonas Lehtinen
 
Introduction to Html5
Introduction to Html5Introduction to Html5
Introduction to Html5
www.netgains.org
 
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 2James Pearce
 
Enjoy the vue.js
Enjoy the vue.jsEnjoy the vue.js
Enjoy the vue.js
TechExeter
 
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 quickstartLinkMe Srl
 
JQuery Mobile UI
JQuery Mobile UIJQuery Mobile UI
JQuery Mobile UI
My own sweet home!
 
`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
Lemberg Solutions
 
2.java script dom
2.java script  dom2.java script  dom
2.java script dom
PhD Research Scholar
 
Private slideshow
Private slideshowPrivate slideshow
Private slideshowsblackman
 
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
Hendy Irawan
 
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
crokitta
 
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
Pablo Garrido
 
Jquery tutorial
Jquery tutorialJquery tutorial
Jquery tutorial
Bui Kiet
 
HTML5 New and Improved
HTML5   New and ImprovedHTML5   New and Improved
HTML5 New and Improved
Timothy Fisher
 
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 2RORLAB
 
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
Alan Hamlett
 
Jinja2 Templates - San Francisco Flask Meetup
Jinja2 Templates - San Francisco Flask MeetupJinja2 Templates - San Francisco Flask Meetup
Jinja2 Templates - San Francisco Flask Meetup
Alan Hamlett
 

Similar to 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
 

Recently uploaded

GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 

Recently uploaded (20)

GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 

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