SlideShare une entreprise Scribd logo
1  sur  46
Télécharger pour lire hors ligne
Introducción a WebComponents
y VisualStudio
VisualStudio
WebComponents
Agenda
 Introducción
 Qué son los WebComponents?
 Mi primer WebComponent
 Construcción de una aplicación
3
Rubén Chavarri
Who are we:
David Chavarri
#DISCLAIMER
const talk = best ? fav_framework : webcomponents;
@pekewake
Introducción al desarrollo web
orientado a webcomponents
@dvdchavarri
El problema de elegir un framework de desarrollo front-end
Front-end Choice Paralisis
@dvdchavarri
Por qué Web Components
Reutilización Encapsulación
Homogeneidad Composición
@dvdchavarri
“ Componentes Web es la tecnología que
permiten definir tus propias etiquetas HTML
personalizadas que incluyen una semántica,
un comportamiento funcional y una lógica
de presentación propia. ”
Recogido en el estándar W3C, 2011
Qué son los WebComponents?
@dvdchavarri
Custom element
Modelo de extensibilidad
que permite definir nuevas
etiquetas o redefinir las
etiquetas estándar HTML
W3C Web Component Especification
Import
Posibilidad de cargar
ficheros de código HTML
dentro de otros ficheros
permitiendo modularizar
elementos y
empaquetarlos.
Shadow Dom
Modelo de encapsulación
que permite aislar el
contenido interno del
componente.
Template
Modelo de renderización
basado en plantillas de
código HTML que sólo
son activadas cuando se
renderiza el componente
@dvdchavarri
Link plunker
Web Components:
VanillaJS Polymer X-tag (micro)
• Diferentes Implementaciones:
@dvdchavarri
Soporte en los Navegadores
@dvdchavarri
Soporte en los Navegadores con Polyfills
@dvdchavarri
Ejemplo
Mi primer Web Component
con Polymer
@dvdchavarri
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-icon/iron-icon.html">
<dom-module id="icon-toggle">
<template>
<style>
stroke: var(--icon-toggle-outline-color, currentcolor); }
:host([pressed]) iron-icon { fill: var(--icon-toggle-pressed-color, currentcolor); }
</style>
<iron-icon icon="polymer"> </iron-icon>
</template>
<script>
Polymer({ /* this is the element's prototype */
is: 'icon-toggle',
properties: {
toggleIcon: String,
pressed: {
type: Boolean,
value: false,
notify: true }
},
listeners: {
'tap': 'toggle'
},
toggle: function() {
this.pressed = !this.pressed;
},
});
</script>
</dom-module>
Imports Mi primer WebComponent
Link plunker
Template
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-icon/iron-icon.html">
<dom-module id="icon-toggle">
<template>
<style>
stroke: var(--icon-toggle-outline-color, currentcolor); }
:host([pressed]) iron-icon { fill: var(--icon-toggle-pressed-color, currentcolor); }
</style>
<iron-icon icon="polymer"></iron-icon>
</template>
<script>
Polymer({ /* this is the element's prototype */
is: 'icon-toggle',
properties: {
toggleIcon: String,
pressed: {
type: Boolean,
value: false,
notify: true }
},
listeners: {
'tap': 'toggle'
},
toggle: function() {
this.pressed = !this.pressed;
},
});
</script>
</dom-module>
Mi primer WebComponent
Link plunker
Link plunker
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-icon/iron-icon.html">
<dom-module id="icon-toggle">
<template>
<style>
stroke: var(--icon-toggle-outline-color, currentcolor); }
:host([pressed]) iron-icon { fill: var(--icon-toggle-pressed-color, currentcolor); }
</style>
<iron-icon icon="polymer"> </iron-icon>
</template>
<script>
Polymer({ /* this is the element's prototype */
is: 'icon-toggle',
properties: {
toggleIcon: String,
pressed: {
type: Boolean,
value: false,
notify: true }
},
listeners: {
'tap': 'toggle'
},
toggle: function() {
this.pressed = !this.pressed;
},
});
</script>
</dom-module>
Custom
Element
Mi primer WebComponent
Ejemplo
Composición de WebComponents
con Polymer
@dvdchavarri
Ejemplo composición de WebComponents
Link plunker
<body unresolved>
<template is="dom-bind">
<google-map map="{{map}}“ latitude="40.4185115“ longitude="-3.7983468" zoom="{{zoom}}">
<google-map-marker latitude="40.4185115" longitude="-3.7983468" title="Go WebComponents!">
</google-map-marker>
</google-map>
<google-map-directions map="{{map}}" start-address="{{start}}“ end-address="{{end}}">
</google-map-directions>
<paper-card elevation="2">
<paper-icon-item>
<iron-icon icon="search" item-icon></iron-icon>
<paper-input label="Start address" value="{{start}}"></paper-input>
</paper-icon-item>
<paper-icon-item>
<iron-icon icon="search" item-icon></iron-icon>
<paper-input label="End address" value="{{end}}"></paper-input>
</paper-icon-item>
<paper-icon-item>
<iron-icon icon="icons:aspect-ratio" item-icon></iron-icon>
<paper-slider min="10" max="20" value="{{zoom}}"></paper-slider>
</paper-icon-item>
</paper-card>
</template>
</body>
Polymer - Catálogo de componentes.
@dvdchavarri
Desarrollo de una Aplicación
con WebComponents
en ASP.NET
@pekewake
Terror
Descomposición de la aplicación
<TODO-APP>
@pekewake
<TODOS><DONE>
@pekewake
<TODO-ELEMENT>
@pekewake
<TODO-API>
@pekewake
<todo-api> <todo-app> <todo-list> <todo-element>
Descomposición de la aplicación en
WebComponents
@pekewake
<todo-api> <todo-app> <todo-list> <todo-element>
@pekewake
<dom-module id="todo-element" attributes="task user rid">
<style> …</style>
<template>
<paper-material class="todo" elevation="1">
<paper-checkbox checked="{{completed}}"></paper-checkbox>
<paper-fab hidden={{editing}} icon="icons:create" on-tap="doEdit" class="edit" mini></paper-fab>
<paper-fab hidden={{!editing}} icon="icons:done" on-tap="doEdit" class="done" mini></paper-fab>
<paper-item hidden="{{editing}}" id="task">{{task}}</paper-item>
<paper-input id="edit" hidden="{{!editing}}" value="{{task}}"></paper-input>
<paper-item class="info">Created by: <span>{{ user }}</span></paper-item>
<paper-item class="info">{{ time }}</paper-item>
</paper-material>
</template>
</dom-module>
<script>
Polymer({
is: "todo-element",
properties: {
user: {type: String}, task: {type: String}, rid: {type: Number},
completed: { observer:’compChaged’ }
editing: { value: false } }
compChanged: function(e){
if(e){ this.fire('complete',this); } },
doEdit: function(e){
this.editing=!this.editing;
if (!this.editing) { this.fire('edit', {rid:this.rid, task:this.task}); } },
}});
</script>
Properties
Events
Template
<todo-element>
<todo-api> <todo-app> <todo-list> <todo-element>
@pekewake
<dom-module id="todo-app">
<style>
…
</style>
<template>
<template is="dom-repeat" items="{{done}}">
<paper-item>{{item.task}}<i >{{item.user}}</i></paper-item>
</template>
<paper-material id="todoEntry" elevation="2">
<paper-input id="tTask" label="Task"></paper-input>
<paper-input id="tUser" char-counter label="Username" ></paper-input>
<paper-fab icon="icons:add" on-tap="postTask"></paper-fab>
</paper-material>
<template is="dom-repeat" items="{{todo}}">
<todo-element user="{{item.user}}" task="{{item.task}}" rid="{{item.rid}}"></todo-element>
</template>
<todo-storage local-list="{{done}}" local-storage="localDone"></todo-storage>
<todo-api local-list="{{todo}}" ></todo-api>
</template>
</dom-module>
<script>
…
</script>
{{done}}
{{todo}}
<todo-api> <todo-app> <todo-list> <todo-element>
@pekewake
<dom-module id="todo-app">
<style>… </style>
<template> …
<paper-material id="todoEntry" elevation="2">
<paper-input id="tTask" label="Task"></paper-input>
<paper-input id="tUser" char-counter label="Username" ></paper-input>
<paper-fab icon="icons:add" on-tap="postTask"></paper-fab>
</paper-material> …
</template>
</dom-module>
<script>
Polymer({
is: "todo-app",
properties: {todo: { type: Array}, done: { type: Array} },
postTask: function(e) {
this.push("todo", { user: usr, task: tsk, rid: this.todo.length });
},
handleComplete: function(e){
var idx = findWithAttr(this.todo, 'rid',e.target.rid);
var itm = this.splice('todo', idx, 1)[0];
},
handleEdit: function(e){
this.set('todo.' + e.target.rid, { task: e.target.task, user: e.target.user, rid: e.target.rid });
},
ready: function(e){
this.addEventListener('complete', this.handleComplete);
this.addEventListener('edit', this.handleEdit);
}
…
</script>
Properties
Events
Template<todo-app>
<todo-api> <todo-app> <todo-list> <todo-element>
@pekewake
<todo-api>
<dom-module id="todo-app">
<style>
…
</style>
<template>
<template is="dom-repeat" items="{{done}}">
<paper-item>{{item.task}}<i style="margin-left: 5px;">{{item.user}}</i></paper-item>
</template>
<paper-material id="todoEntry" elevation="2">
<paper-input id="tTask" label="Task"></paper-input>
<paper-input id="tUser" char-counter label="Username" ></paper-input>
<paper-fab icon="icons:add" on-tap="postTask"></paper-fab>
</paper-material>
<template is="dom-repeat" items="{{todo}}">
<todo-element user="{{item.user}}" task="{{item.task}}" rid="{{item.rid}}"></todo-element>
</template>
<todo-storage local-list="{{done}}" local-storage="localDone"></todo-storage>
<todo-api local-list="{{todo}}" ></todo-api>
</template>
</dom-module>
<script>
…
</script>
<todo-storage>
¿Cómo nos comunicamos
con Backend?
ASP.NET
@pekewake
<todo-api> <todo-app> <todo-list> <todo-element>
Cómo nos comunicamos con Back-end?
Web API
<todo-api>
<dom-module id="todo-api">
<template>
<iron-ajax id="ajax“ handle-as="json“ content-type="application/json"></iron-ajax>
</template>
</dom-module>
<script>
Polymer({
is: 'todo-api',
properties: {
localList: { value: [] }
},
observers: [
'listChange( localList.* )'
],
listChange: function (changeRecord) {
var _this = this;
if (changeRecord.path == 'localList.splices') {
changeRecord.value.indexSplices.forEach(function (s) {
s.removed.forEach(function (item) {
_this.deleteTask(item);
});
if (s.addedCount > 0) {
_this.addTask(s);
}
}, this);
} else {
if (changeRecord.value.rid != null) {
_this.updateTask(changeRecord.value);
}
}
},
addTask: function (task) {
this.$.ajax.url = [baseUrl, "api/todo"].join('/');
this.$.ajax.body = JSON.stringify({ rid: task.object[task.index].rid,
user: task.object[task.index].user,
task: task.object[task.index].task });
this.$.ajax.method = "POST";
this.$.ajax.generateRequest();
},
deleteTask: function (task) {
this.$.ajax.url = [baseUrl, "api/todo", task.rid].join('/');
this.$.ajax.method = "DELETE";
this.$.ajax.generateRequest();
},
updateTask: function (task) {
this.$.ajax.url = [baseUrl, "api/todo", task.rid].join('/');
this.$.ajax.body = JSON.stringify({ rid: task.rid, user: task.user, task: task.task });
this.$.ajax.method = "PUT";
this.$.ajax.generateRequest();},
ready: function (e) {
var _this = this;
this.$.ajax.url = [baseUrl, "api/todo"].join('/');
this.$.ajax.method = “GET";
this.$.ajax.generateRequest().completes.then(function (request) {
_this.localList = request.response;
});
Web API
TodoController.csnamespace PolymerApi.Controllers
{
[Route("api/[controller]")]
public class TodoController : Controller
{
static private List<Todo> todolist = new List<Todo>();
public TodoController()
{
if (todolist.Count == 0)
{ todolist.Add(new Todo { rid = 0, task = "Happy Polymer Coding", user = "Ruben Chavarri", time = "" }); }
}
// GET: api/values
[HttpGet]
public IEnumerable<Todo> Get()
{
return todolist;
}
// GET api/values/5
[HttpGet("{id:int}")]
public IActionResult Get ( int id)
{
return new ObjectResult(todolist[id]);
}
// PUT api/values/5
[HttpPut("{id:int}")]
public IActionResult Put ( int id, [FromBody] Todo todo)
{
var index = todolist.FindIndex(row => row.rid == id);
todolist[index] = todo;
return new ObjectResult(todo);
}
// POST api/values
[HttpPost]
public IActionResult Post( [FromBody] Todo todo)
{
todolist.Add(todo);
return new ObjectResult(todo);
}
// DELETE api/values/5
[HttpDelete("{id:int}")]
public IActionResult Delete (int id)
{
var index = todolist.FindIndex(row => row.rid == id);
todolist.RemoveAt(index);
return new HttpStatusCodeResult(200);
}
}
}
Demo
ToDo List
@pekewake
WebComponents
Nuevo “Ciclo de desarrollo”
@pekewake
Implementación de WebComponents
Generadores y Plantillas
Es una buena práctica
partir de una plantilla
(a partir de Yeoman o
github seed-element)
Desarrollo
Diseño del
webcomponente
orientando a la
reutilización
Despliegue
Tras el desarrollo del
webcomponentes se
compacta con
gulp/grunt
(minify, resize img,
compile less/sass…).
Publicación
Se empaqueta y publica
en el catalogo de
webcomponentes
(public/privado) para la
posterior reutilización
@pekewake
Uso de WebComponents
Selección de
Webcomponents,
procedente de repositorios
públicos/privados.
Instalación/Descarga
Descarga de
components mediante
bower (gestor de
paquetes)
Uso de componentes
Se incluye import en la
aplicación y se utiliza
como otra etiqueta html
standar
@pekewake
Thanks!@pekewake @dvdchavarri
45
Rubén Chavarri
Who are we:
David Chavarri
Sources
Ejemplos y fuentes:
http://plnkr.co/edit/fmWG1YIBS6OaItdVe68v?p=preview
http://plnkr.co/edit/BoW1xTNDEo3MybMMSgfK?p=preview
http://plnkr.co/edit/SO7fFJVgBwNqt7mHkhNw?p=preview
https://github.com/Twiinlab/PolymerApiVS
Referencias y menciones utilizadas en las slides:
https://speakerdeck.com/robdodson/end-to-end-with-polymer
http://es.slideshare.net/jvelez77/orientando-a-componentes-la-web-55613507
https://scotch.io/tutorials/build-a-real-time-polymer-to-do-app
Otros links de interes:
https://css-tricks.com/modular-future-web-components
http://webcomponents.org/articles/why-web-components
http://www.html5rocks.com/en/tutorials/webcomponents/customelements/
https://www.polymer-project.org/1.0/
https://elements.polymer-project.org/

Contenu connexe

Introduccion WebComponents y Visual Studio

  • 1. Introducción a WebComponents y VisualStudio VisualStudio WebComponents
  • 2. Agenda  Introducción  Qué son los WebComponents?  Mi primer WebComponent  Construcción de una aplicación
  • 3. 3 Rubén Chavarri Who are we: David Chavarri
  • 4. #DISCLAIMER const talk = best ? fav_framework : webcomponents; @pekewake
  • 5. Introducción al desarrollo web orientado a webcomponents @dvdchavarri
  • 6. El problema de elegir un framework de desarrollo front-end Front-end Choice Paralisis @dvdchavarri
  • 7. Por qué Web Components Reutilización Encapsulación Homogeneidad Composición @dvdchavarri
  • 8. “ Componentes Web es la tecnología que permiten definir tus propias etiquetas HTML personalizadas que incluyen una semántica, un comportamiento funcional y una lógica de presentación propia. ” Recogido en el estándar W3C, 2011 Qué son los WebComponents? @dvdchavarri
  • 9. Custom element Modelo de extensibilidad que permite definir nuevas etiquetas o redefinir las etiquetas estándar HTML W3C Web Component Especification Import Posibilidad de cargar ficheros de código HTML dentro de otros ficheros permitiendo modularizar elementos y empaquetarlos. Shadow Dom Modelo de encapsulación que permite aislar el contenido interno del componente. Template Modelo de renderización basado en plantillas de código HTML que sólo son activadas cuando se renderiza el componente @dvdchavarri Link plunker
  • 10. Web Components: VanillaJS Polymer X-tag (micro) • Diferentes Implementaciones: @dvdchavarri
  • 11. Soporte en los Navegadores @dvdchavarri
  • 12. Soporte en los Navegadores con Polyfills @dvdchavarri
  • 13. Ejemplo Mi primer Web Component con Polymer @dvdchavarri
  • 14. <link rel="import" href="../polymer/polymer.html"> <link rel="import" href="../iron-icon/iron-icon.html"> <dom-module id="icon-toggle"> <template> <style> stroke: var(--icon-toggle-outline-color, currentcolor); } :host([pressed]) iron-icon { fill: var(--icon-toggle-pressed-color, currentcolor); } </style> <iron-icon icon="polymer"> </iron-icon> </template> <script> Polymer({ /* this is the element's prototype */ is: 'icon-toggle', properties: { toggleIcon: String, pressed: { type: Boolean, value: false, notify: true } }, listeners: { 'tap': 'toggle' }, toggle: function() { this.pressed = !this.pressed; }, }); </script> </dom-module> Imports Mi primer WebComponent Link plunker
  • 15. Template <link rel="import" href="../polymer/polymer.html"> <link rel="import" href="../iron-icon/iron-icon.html"> <dom-module id="icon-toggle"> <template> <style> stroke: var(--icon-toggle-outline-color, currentcolor); } :host([pressed]) iron-icon { fill: var(--icon-toggle-pressed-color, currentcolor); } </style> <iron-icon icon="polymer"></iron-icon> </template> <script> Polymer({ /* this is the element's prototype */ is: 'icon-toggle', properties: { toggleIcon: String, pressed: { type: Boolean, value: false, notify: true } }, listeners: { 'tap': 'toggle' }, toggle: function() { this.pressed = !this.pressed; }, }); </script> </dom-module> Mi primer WebComponent Link plunker
  • 16. Link plunker <link rel="import" href="../polymer/polymer.html"> <link rel="import" href="../iron-icon/iron-icon.html"> <dom-module id="icon-toggle"> <template> <style> stroke: var(--icon-toggle-outline-color, currentcolor); } :host([pressed]) iron-icon { fill: var(--icon-toggle-pressed-color, currentcolor); } </style> <iron-icon icon="polymer"> </iron-icon> </template> <script> Polymer({ /* this is the element's prototype */ is: 'icon-toggle', properties: { toggleIcon: String, pressed: { type: Boolean, value: false, notify: true } }, listeners: { 'tap': 'toggle' }, toggle: function() { this.pressed = !this.pressed; }, }); </script> </dom-module> Custom Element Mi primer WebComponent
  • 18. Ejemplo composición de WebComponents Link plunker <body unresolved> <template is="dom-bind"> <google-map map="{{map}}“ latitude="40.4185115“ longitude="-3.7983468" zoom="{{zoom}}"> <google-map-marker latitude="40.4185115" longitude="-3.7983468" title="Go WebComponents!"> </google-map-marker> </google-map> <google-map-directions map="{{map}}" start-address="{{start}}“ end-address="{{end}}"> </google-map-directions> <paper-card elevation="2"> <paper-icon-item> <iron-icon icon="search" item-icon></iron-icon> <paper-input label="Start address" value="{{start}}"></paper-input> </paper-icon-item> <paper-icon-item> <iron-icon icon="search" item-icon></iron-icon> <paper-input label="End address" value="{{end}}"></paper-input> </paper-icon-item> <paper-icon-item> <iron-icon icon="icons:aspect-ratio" item-icon></iron-icon> <paper-slider min="10" max="20" value="{{zoom}}"></paper-slider> </paper-icon-item> </paper-card> </template> </body>
  • 19. Polymer - Catálogo de componentes. @dvdchavarri
  • 20. Desarrollo de una Aplicación con WebComponents en ASP.NET @pekewake
  • 22. Descomposición de la aplicación
  • 27. <todo-api> <todo-app> <todo-list> <todo-element> Descomposición de la aplicación en WebComponents @pekewake
  • 28. <todo-api> <todo-app> <todo-list> <todo-element> @pekewake
  • 29. <dom-module id="todo-element" attributes="task user rid"> <style> …</style> <template> <paper-material class="todo" elevation="1"> <paper-checkbox checked="{{completed}}"></paper-checkbox> <paper-fab hidden={{editing}} icon="icons:create" on-tap="doEdit" class="edit" mini></paper-fab> <paper-fab hidden={{!editing}} icon="icons:done" on-tap="doEdit" class="done" mini></paper-fab> <paper-item hidden="{{editing}}" id="task">{{task}}</paper-item> <paper-input id="edit" hidden="{{!editing}}" value="{{task}}"></paper-input> <paper-item class="info">Created by: <span>{{ user }}</span></paper-item> <paper-item class="info">{{ time }}</paper-item> </paper-material> </template> </dom-module> <script> Polymer({ is: "todo-element", properties: { user: {type: String}, task: {type: String}, rid: {type: Number}, completed: { observer:’compChaged’ } editing: { value: false } } compChanged: function(e){ if(e){ this.fire('complete',this); } }, doEdit: function(e){ this.editing=!this.editing; if (!this.editing) { this.fire('edit', {rid:this.rid, task:this.task}); } }, }}); </script> Properties Events Template <todo-element>
  • 30. <todo-api> <todo-app> <todo-list> <todo-element> @pekewake
  • 31. <dom-module id="todo-app"> <style> … </style> <template> <template is="dom-repeat" items="{{done}}"> <paper-item>{{item.task}}<i >{{item.user}}</i></paper-item> </template> <paper-material id="todoEntry" elevation="2"> <paper-input id="tTask" label="Task"></paper-input> <paper-input id="tUser" char-counter label="Username" ></paper-input> <paper-fab icon="icons:add" on-tap="postTask"></paper-fab> </paper-material> <template is="dom-repeat" items="{{todo}}"> <todo-element user="{{item.user}}" task="{{item.task}}" rid="{{item.rid}}"></todo-element> </template> <todo-storage local-list="{{done}}" local-storage="localDone"></todo-storage> <todo-api local-list="{{todo}}" ></todo-api> </template> </dom-module> <script> … </script> {{done}} {{todo}}
  • 32. <todo-api> <todo-app> <todo-list> <todo-element> @pekewake
  • 33. <dom-module id="todo-app"> <style>… </style> <template> … <paper-material id="todoEntry" elevation="2"> <paper-input id="tTask" label="Task"></paper-input> <paper-input id="tUser" char-counter label="Username" ></paper-input> <paper-fab icon="icons:add" on-tap="postTask"></paper-fab> </paper-material> … </template> </dom-module> <script> Polymer({ is: "todo-app", properties: {todo: { type: Array}, done: { type: Array} }, postTask: function(e) { this.push("todo", { user: usr, task: tsk, rid: this.todo.length }); }, handleComplete: function(e){ var idx = findWithAttr(this.todo, 'rid',e.target.rid); var itm = this.splice('todo', idx, 1)[0]; }, handleEdit: function(e){ this.set('todo.' + e.target.rid, { task: e.target.task, user: e.target.user, rid: e.target.rid }); }, ready: function(e){ this.addEventListener('complete', this.handleComplete); this.addEventListener('edit', this.handleEdit); } … </script> Properties Events Template<todo-app>
  • 34. <todo-api> <todo-app> <todo-list> <todo-element> @pekewake
  • 35. <todo-api> <dom-module id="todo-app"> <style> … </style> <template> <template is="dom-repeat" items="{{done}}"> <paper-item>{{item.task}}<i style="margin-left: 5px;">{{item.user}}</i></paper-item> </template> <paper-material id="todoEntry" elevation="2"> <paper-input id="tTask" label="Task"></paper-input> <paper-input id="tUser" char-counter label="Username" ></paper-input> <paper-fab icon="icons:add" on-tap="postTask"></paper-fab> </paper-material> <template is="dom-repeat" items="{{todo}}"> <todo-element user="{{item.user}}" task="{{item.task}}" rid="{{item.rid}}"></todo-element> </template> <todo-storage local-list="{{done}}" local-storage="localDone"></todo-storage> <todo-api local-list="{{todo}}" ></todo-api> </template> </dom-module> <script> … </script> <todo-storage>
  • 36. ¿Cómo nos comunicamos con Backend? ASP.NET @pekewake
  • 37. <todo-api> <todo-app> <todo-list> <todo-element> Cómo nos comunicamos con Back-end? Web API
  • 38. <todo-api> <dom-module id="todo-api"> <template> <iron-ajax id="ajax“ handle-as="json“ content-type="application/json"></iron-ajax> </template> </dom-module> <script> Polymer({ is: 'todo-api', properties: { localList: { value: [] } }, observers: [ 'listChange( localList.* )' ], listChange: function (changeRecord) { var _this = this; if (changeRecord.path == 'localList.splices') { changeRecord.value.indexSplices.forEach(function (s) { s.removed.forEach(function (item) { _this.deleteTask(item); }); if (s.addedCount > 0) { _this.addTask(s); } }, this); } else { if (changeRecord.value.rid != null) { _this.updateTask(changeRecord.value); } } }, addTask: function (task) { this.$.ajax.url = [baseUrl, "api/todo"].join('/'); this.$.ajax.body = JSON.stringify({ rid: task.object[task.index].rid, user: task.object[task.index].user, task: task.object[task.index].task }); this.$.ajax.method = "POST"; this.$.ajax.generateRequest(); }, deleteTask: function (task) { this.$.ajax.url = [baseUrl, "api/todo", task.rid].join('/'); this.$.ajax.method = "DELETE"; this.$.ajax.generateRequest(); }, updateTask: function (task) { this.$.ajax.url = [baseUrl, "api/todo", task.rid].join('/'); this.$.ajax.body = JSON.stringify({ rid: task.rid, user: task.user, task: task.task }); this.$.ajax.method = "PUT"; this.$.ajax.generateRequest();}, ready: function (e) { var _this = this; this.$.ajax.url = [baseUrl, "api/todo"].join('/'); this.$.ajax.method = “GET"; this.$.ajax.generateRequest().completes.then(function (request) { _this.localList = request.response; });
  • 39. Web API TodoController.csnamespace PolymerApi.Controllers { [Route("api/[controller]")] public class TodoController : Controller { static private List<Todo> todolist = new List<Todo>(); public TodoController() { if (todolist.Count == 0) { todolist.Add(new Todo { rid = 0, task = "Happy Polymer Coding", user = "Ruben Chavarri", time = "" }); } } // GET: api/values [HttpGet] public IEnumerable<Todo> Get() { return todolist; } // GET api/values/5 [HttpGet("{id:int}")] public IActionResult Get ( int id) { return new ObjectResult(todolist[id]); } // PUT api/values/5 [HttpPut("{id:int}")] public IActionResult Put ( int id, [FromBody] Todo todo) { var index = todolist.FindIndex(row => row.rid == id); todolist[index] = todo; return new ObjectResult(todo); } // POST api/values [HttpPost] public IActionResult Post( [FromBody] Todo todo) { todolist.Add(todo); return new ObjectResult(todo); } // DELETE api/values/5 [HttpDelete("{id:int}")] public IActionResult Delete (int id) { var index = todolist.FindIndex(row => row.rid == id); todolist.RemoveAt(index); return new HttpStatusCodeResult(200); } } }
  • 41. WebComponents Nuevo “Ciclo de desarrollo” @pekewake
  • 42. Implementación de WebComponents Generadores y Plantillas Es una buena práctica partir de una plantilla (a partir de Yeoman o github seed-element) Desarrollo Diseño del webcomponente orientando a la reutilización Despliegue Tras el desarrollo del webcomponentes se compacta con gulp/grunt (minify, resize img, compile less/sass…). Publicación Se empaqueta y publica en el catalogo de webcomponentes (public/privado) para la posterior reutilización @pekewake
  • 43. Uso de WebComponents Selección de Webcomponents, procedente de repositorios públicos/privados. Instalación/Descarga Descarga de components mediante bower (gestor de paquetes) Uso de componentes Se incluye import en la aplicación y se utiliza como otra etiqueta html standar @pekewake
  • 45. 45 Rubén Chavarri Who are we: David Chavarri
  • 46. Sources Ejemplos y fuentes: http://plnkr.co/edit/fmWG1YIBS6OaItdVe68v?p=preview http://plnkr.co/edit/BoW1xTNDEo3MybMMSgfK?p=preview http://plnkr.co/edit/SO7fFJVgBwNqt7mHkhNw?p=preview https://github.com/Twiinlab/PolymerApiVS Referencias y menciones utilizadas en las slides: https://speakerdeck.com/robdodson/end-to-end-with-polymer http://es.slideshare.net/jvelez77/orientando-a-componentes-la-web-55613507 https://scotch.io/tutorials/build-a-real-time-polymer-to-do-app Otros links de interes: https://css-tricks.com/modular-future-web-components http://webcomponents.org/articles/why-web-components http://www.html5rocks.com/en/tutorials/webcomponents/customelements/ https://www.polymer-project.org/1.0/ https://elements.polymer-project.org/

Notes de l'éditeur

  1. Siguiendo en la línea de eventos relacionados con Front-End, tras la ultima charla de Ionic, hablamos con Luis para hablar del desarrollo web orientado a Webcomponents con VisualStudio, las herramientas que andamos familiarizados.
  2. Comenzaremos con una introducción para situarnos y que es esto de los Webcomponents. Aunque lo que nos interesa especialmente ver de forma práctica a través de ejemplos, costruiremos nuestro primer Webcomponents, veremos unos cuantos ejemplos de como se combinan y terminaremos viendo una aplicación.
  3. Un poco de nuestras historia, que hemos aprendido por el camino Participado en el framework de desarrollo de aplicaciones orientado a componentes dentro del Banco Animados por aprender nuevos frameworks, asiduos frecuentes a meetups y hackathones
  4. #DISCLAIMER const talk = best ? fav_famework : react; * No estamos aquí para decir que Webcomponents es el mejor, que es mejor que Angular, que React o Backbone. * Lo way, lo que mola es observar y decidir que es lo mejor para tu producto. Hay que ser responsable. Importante contar con una tecnología que tenga una comunidad detrás y que se esté implantando en clientes finales (Polymer en SalesForce, Github y por proyectos mas cercanos en ING y en otros principales bancos. * Los frameworks intentan abarcar todo pero no son capaces de apretar en todas sus partes. * Por situarnos: Webcomponents (librería) para cubrir necesidades especificas y Angular (es un framework) - Pregunta para Google: Porque dos frameworks diferentes? AngularJS y Polymer. Porque realmetne no existe la formula perfecta! - Angular? Es necesario adaptar toda la empresa para utilizar un framework.
  5. * Preguntar a la gente en que desarrolla cada uno. Todos estos frameworks tienen en común, que desarrollan sus propios componentes, a su manera. Estaría fenomenal disponer de un estándar que especifique como implementar estos componentes y poder compartirlos entre ellos.
  6. La construcción de componentes Reutilizables. Eje principal! Encapsulación de funcionalidad y aspecto. Que estos componentes absorban la complejidad del diseño, capaces de adaptarse al espacio, dispositivo, etc. de forma transparente para el maquetador. Desarrollo homogéneo en base al estándar. Construcción de interefaces homogenea, que facilita el uso de la tecnología (material design: modelo de look&feel, componentes) Construcción de Aplicaciones Web por Composición por parte de los diseñadores reutilizando componentes con UX, lo que produce una aplicación con la Expereciencia de usuario coherente.
  7. dnvm use -r clr -arch x86 1.0.0-rc1-update1 dnx web
  8. Componentes Visuales + Componente Datos Analisis de cada una de las piezas y como se comunican Binding + Eventos