Introduccion WebComponents y Visual Studio

46
Introducción a WebComponents y VisualStudio VisualStud io WebComponents

Transcript of Introduccion WebComponents y Visual Studio

Page 1: Introduccion WebComponents y Visual Studio

Introducción a WebComponents y VisualStudio

VisualStudio

WebComponents

Page 2: Introduccion WebComponents y Visual Studio

Agenda Introducción Qué son los

WebComponents? Mi primer WebComponent Construcción de una

aplicación

Page 3: Introduccion WebComponents y Visual Studio

3

Software Engineer at [email protected]@pekewakehttps://github.com/ruchavarri

Rubén Chavarri

Who are we:

Software Architect at Ciber Españ[email protected]@dvdchavarrihttps://github.com/dvdchavarri

David Chavarri

Page 4: Introduccion WebComponents y Visual Studio

#DISCLAIMERconst talk = best ? fav_framework :

webcomponents;

@pekewake

Page 5: Introduccion WebComponents y Visual Studio

Introducción al desarrollo web orientado a webcomponents

@dvdchavarri

Page 6: Introduccion WebComponents y Visual Studio

El problema de elegir un framework de desarrollo front-end

Front-end Choice Paralisis

@dvdchavarri

Page 7: Introduccion WebComponents y Visual Studio

Por qué Web Components

Reutilización Encapsulación

Homogeneidad

Composición

@dvdchavarri

Page 8: Introduccion WebComponents y Visual Studio

“ 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

Page 9: Introduccion WebComponents y Visual Studio

Custom element

Modelo de extensibilidad que permite definir nuevas etiquetas o redefinir las etiquetas estándar HTML

W3C Web Component Especification

ImportPosibilidad de cargar ficheros de código HTML dentro de otros ficheros permitiendo modularizar elementos y empaquetarlos.

Shadow DomModelo de encapsulación que permite aislar el contenido interno del componente.

TemplateModelo de renderización basado en plantillas de código HTML que sólo son activadas cuando se renderiza el componente

@dvdchavarri Link plunker

Page 10: Introduccion WebComponents y Visual Studio

Web Components:

VanillaJS Polymer X-tag (micro)

• Diferentes Implementaciones:

@dvdchavarri

Page 11: Introduccion WebComponents y Visual Studio

Soporte en los Navegadores

@dvdchavarri

Page 12: Introduccion WebComponents y Visual Studio

Soporte en los Navegadores con Polyfills

@dvdchavarri

Page 13: Introduccion WebComponents y Visual Studio

EjemploMi primer Web Component con Polymer

@dvdchavarri

Page 14: Introduccion WebComponents y Visual Studio

<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

Page 15: Introduccion WebComponents y Visual Studio

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

Page 16: Introduccion WebComponents y Visual Studio

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>

CustomElement

Mi primer WebComponent

Page 17: Introduccion WebComponents y Visual Studio

EjemploComposición de WebComponentscon Polymer

@dvdchavarri

Page 18: Introduccion WebComponents y Visual Studio

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>

Page 19: Introduccion WebComponents y Visual Studio

Polymer - Catálogo de componentes.

@dvdchavarri

Page 20: Introduccion WebComponents y Visual Studio

Desarrollo de una Aplicacióncon WebComponentsen ASP.NET

@pekewake

Page 21: Introduccion WebComponents y Visual Studio

Terror

Page 22: Introduccion WebComponents y Visual Studio

Descomposición de la aplicación

Page 23: Introduccion WebComponents y Visual Studio

<TODO-APP>@pekewake

Page 24: Introduccion WebComponents y Visual Studio

<TODOS><DONE>@pekewake

Page 25: Introduccion WebComponents y Visual Studio

<TODO-ELEMENT>@pekewake

Page 26: Introduccion WebComponents y Visual Studio

<TODO-API>@pekewake

Page 27: Introduccion WebComponents y Visual Studio

<todo-api>

<todo-app> <todo-list>

<todo-element>

Descomposición de la aplicación en

WebComponents

@pekewake

Page 28: Introduccion WebComponents y Visual Studio

<todo-api>

<todo-app> <todo-list>

<todo-element>

@pekewake

Page 29: Introduccion WebComponents y Visual Studio

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

Page 30: Introduccion WebComponents y Visual Studio

<todo-api>

<todo-app> <todo-list>

<todo-element>

@pekewake

Page 31: Introduccion WebComponents y Visual Studio

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

Page 32: Introduccion WebComponents y Visual Studio

<todo-api>

<todo-app> <todo-list>

<todo-element>

@pekewake

Page 33: Introduccion WebComponents y Visual Studio

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

Page 34: Introduccion WebComponents y Visual Studio

<todo-api>

<todo-app> <todo-list>

<todo-element>

@pekewake

Page 35: Introduccion WebComponents y Visual Studio

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

Page 36: Introduccion WebComponents y Visual Studio

¿Cómo nos comunicamos con Backend?

ASP.NET

@pekewake

Page 37: Introduccion WebComponents y Visual Studio

<todo-api>

<todo-app> <todo-list>

<todo-element>

Cómo nos comunicamos con Back-end?

Web API

Page 38: Introduccion WebComponents y Visual Studio

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

</script>

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

Page 39: Introduccion WebComponents y Visual Studio

Web API

TodoController.cs

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

Page 40: Introduccion WebComponents y Visual Studio

DemoToDo List

@pekewake

Page 41: Introduccion WebComponents y Visual Studio

WebComponentsNuevo “Ciclo de desarrollo”

@pekewake

Page 42: Introduccion WebComponents y Visual Studio

Implementación de WebComponents

Generadores y PlantillasEs 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

DespliegueTras el desarrollo del webcomponentes se compacta con gulp/grunt (minify, resize img, compile less/sass…).

PublicaciónSe empaqueta y publica en el catalogo de webcomponentes (public/privado) para la posterior reutilización

@pekewake

Page 43: Introduccion WebComponents y Visual Studio

Uso de WebComponents

Selección de Webcomponents, procedente de repositorios públicos/privados.

Instalación/DescargaDescarga de components mediante bower (gestor de paquetes)

Uso de componentesSe incluye import en la aplicación y se utiliza como otra etiqueta html standar

@pekewake

Page 44: Introduccion WebComponents y Visual Studio

Thanks!@pekewake @dvdchavarri

Page 45: Introduccion WebComponents y Visual Studio

45

Software Engineer at [email protected]@pekewakehttps://github.com/ruchavarri

Rubén Chavarri

Who are we:

Software Architect at Ciber Españ[email protected]@dvdchavarrihttps://github.com/dvdchavarri

David Chavarri

Page 46: Introduccion WebComponents y Visual Studio

SourcesEjemplos y fuentes:http://plnkr.co/edit/fmWG1YIBS6OaItdVe68v?p=preview

http://plnkr.co/edit/BoW1xTNDEo3MybMMSgfK?p=previewhttp://plnkr.co/edit/SO7fFJVgBwNqt7mHkhNw?p=previewhttps://github.com/Twiinlab/PolymerApiVSReferencias 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-55613507https://scotch.io/tutorials/build-a-real-time-polymer-to-do-appOtros links de interes:https://css-tricks.com/modular-future-web-componentshttp://webcomponents.org/articles/why-web-componentshttp://www.html5rocks.com/en/tutorials/webcomponents/customelements/

https://www.polymer-project.org/1.0/https://elements.polymer-project.org/