JavierVélezReyes@javiervelezreye
ElProyectoPolymer
ProgramaciónOrientadaaComponentesWeb
Febrero2015
@javiervelezreye2
AutorElProyectoPolymer
Licenciadoeninformá1caporlaUPMdesdeelaño2001ydoctoren informá1ca por la UNED desde el año 2009, Javier esinves1gadorysulíneadetrabajoactualsecentraenlainnovaciónydesarrollodetecnologíasdeComponentesWeb.Ademásrealizaac1vidades de evangelización y divulgación en diversascomunidadesIT,esPolymerPolytechnicSpeakeryco-organizadordelgrupoPolymerSpainqueconformaunacomunidaddeinterésde ámbito nacional en relación al framework Polymer y a lastecnologíasdeComponentesWeb.
I.¿QuiénSoy?
II.¿AQuéMeDedico?
@javiervelezreye
linkedin.com/in/javiervelezreyes
gplus.to/javiervelezreyes
jvelez77
javiervelezreyes
youtube.com/user/javiervelezreyes
PolymerPolytechnicSpeaker
Co-organizadordePolymerSpain
EvangelizaciónWeb
DesarrolladorJSFullstack
ArquitecturaWeb
Formación&ConsultoríaIT
e-learning
JavierVélezReyes@javiervelezreye
1Introducción§ QuéesunComponenteWeb§ PorQuélosComponentesWeb§ LaWebComoPlataformadeComponentes§ UnNuevoModelodeRoles
Introd
ucción
ElProyectoPo
lymer
@javiervelezreye4
IntroducciónElProyectoPolymer
QuéSonLosComponentesWeb
La tecnología de Componentes Web proporcionaunmecanismopara construirnuevase1quetasdeautor personalizadas que incluyen una semán1ca,un comportamiento funcional y una lógica depresentaciónpropia.
E1quetasdeAutorComponentesWeb
@javiervelezreye5
IntroducciónElProyectoPolymer
PorQuéComponentesWeb
Un Componente Web encapsula cierta lógicafuncional y presentacional elaborada que seac1va desde el navegador como una simplee1quetaestándardeHTML.
EncapsulaciónDeLaLógica
ComportamientoAdaptaRvoLos componentes se desarrollan para hacerseresponsablesdelages1óndelespacioeneláreade presentación, de las necesidades deaccesibilidad y las preocupaciones generales deusabilidad.
RWD&AWD
AccesibilidadUsabilidad
@javiervelezreye6
IntroducciónPrincipiosdeDiseñoenComponentesWeb
PorQuéComponentesWeb
Los componentes Web también fomentan unproceso de diseño Web que 1ende a lahomogenización loquedesdeunpuntodevistacorpora1voresultaventajoso.
HomogenizaciónDeldiseño
GesRónDeLaEvoluciónCentralizadaLa lógica de presentación de los componentesWeb se puede adaptar evolu1vamente bajodemanda de las necesidades empresariales sinimpactar en el correcto funcionamiento de losaplica1vos y si1os web que hacen uso de losmismos.
Restaurante Diversia 9.7 (51)
Casa de Campo Puerta del Sol Plaza Mayor
LíneaevoluDva
t1 t2 t3
Losusuariospercibenloscambiosinstantáneamente
v1 v2 v3
@javiervelezreye7
IntroducciónElProyectoPolymer
PorQuéComponentesWeb
La tecnología de componentes Web ofrece laposibilidad de exponer los servicios de unaorganización en forma de un conjunto dee1quetasvisualesqueconectanconcapacidadesdenegocio.
OrientaciónALaVista
ConstrucciónComposiRvaComo cualquier otra e1queta estándar loscomponentesWebpuedenconectarsedeformacomposi1va a través de las relaciones deanidamiento y propagación de eventos quesoportalaWeb.
CRUD
ServiciosREST
HTTP
UsuarioProgramador
UsuarioFinal
LoscomponentesWebestánorientaciónalavista
@javiervelezreye8
IntroducciónElProyectoPolymer
LaWebComoPlataformaDeComponentes LaWebsepresentacomounaplataformadehospedajeparaunacoleccióndecomponentes
con un comportamiento funcional subyacente que se comunican y coordinan entre si, deacuerdo a diferentes esquemas para ofrecer servicios de valor en el contexto de la páginadondeseinscriben.
Incluye todas las nuevas capacida-des que exDenden la Web comoplataformadeorientaciónacompo-nentes
Plataforma
Capacidades funcionales sobrela plataforma que simplificanel proceso de desarrollo deComponentesWeb
Core
Aplicaciones orientadas acomponentesalserviciodelosusuariosdelaWeb
Aplicaciones
Componentesestándardedicadosadar respuesta a necesidadesrecurrentes de control o UI quesurgeneneldesarrolloorientadoaComponentesWeb
Elementos
@javiervelezreye9
IntroducciónElProyectoPolymer
UnNuevoModeloDeRoles Convieneseñalarque,enelmarcodeestenuevoprocesodeconstruccióndesolucionespara
laWebbasadasencomponentes,serequierennuevosrolesdeespecializacióntécnicayflujosdetrabajoestablecidos.Acon1nuaciónbosquejamoslosmismos.
DiseñadorWebEsDlizaloscontenidosde
acuerdoadirectricespresentacionales
MaquetadorWebEstablecelaestructuradeloscontenidosdeacuerdoadirectricessemánDcas
Estableceelmodelodecomportamientoenreacciónaloseventosdeinteraccióndelusuario
CSS
JS
EnlaWebClásica…
.className
HTML
ProgramadorWeb
@javiervelezreye10
IntroducciónElProyectoPolymer
UnNuevoModeloDeRoles
Convieneseñalarque,enelmarcodeestenuevoprocesodeconstruccióndesolucionesparalaWebbasadasencomponentes,serequierennuevosrolesdeespecializacióntécnicayflujosdetrabajoestablecidos.Acon1nuaciónbosquejamoslosmismos.
DiseñadordeComponentesDefineelmodeloderenderingdelcomponentedeacuerdoa
directricesdeesDlo
Establecelaestructuradeloscontenidosinternosquepresentaelcomponentecuandoserenderiza
ProgramadordeComponentesEstableceelmodelodecomportamientosubyacentequeseacDvacuandoserenderizaelcomponente
CSS
JS
EnlaWebOrientadaaComponentes…
<con
tent>
.className
HTML
MaquetadordeComponentes
@javiervelezreye11
IntroducciónElProyectoPolymer
UnNuevoModeloDeRoles
Convieneseñalarque,enelmarcodeestenuevoprocesodeconstruccióndesolucionesparalaWebbasadasencomponentes,serequierennuevosrolesdeespecializacióntécnicayflujosdetrabajoestablecidos.Acon1nuaciónbosquejamoslosmismos.
CSS
JS
EnlaWebOrientadaaComponentes…
cssbinding
HTML
.className
DiseñadordeComponentesDefineelmodeloderenderingdelcomponentedeacuerdoa
directricesdeesDlo
Establecelaestructuradeloscontenidosinternosquepresentaelcomponentecuandoserenderiza
ProgramadordeComponentesEstableceelmodelodecomportamientosubyacentequeseacDvacuandoserenderizaelcomponente
MaquetadordeComponentes
JavierVélezReyes@javiervelezreye
2EstándaresEnComponentesWeb
§ ModelodeEncapsulamiento.ShadowDOM§ ModelodeRenderizado.HTMLTemplates§ ModelodeExtensión.CustomElements§ ModelodeModularización.HTMLImports
Introd
ucción
ElProyectoPo
lymer
@javiervelezreye13
EstándaresEnComponentesWebElProyectoPolymer
4EstándaresIndependientes ElmodelodecomponentesparalaWebdefinidoporlaW3Cconsiste
en cuatro especificaciones tecnológicamente independientes quecubrendis1ntosaspectosdelprocesoconstruc1vo.Alolargodeestecapítulo revisaremos los Estándares En Componentes Web que semanejanenrelaciónatalesespecificaciones.
ShadowDOM
Ofrece un modelo de encapsula-miento que permite aislar elcontenidointernodelcomponentedeaquélen lapáginadondeésteesrenderizado
HTMLTemplates
Ofrece un modelo de construcciónbasado en planDllas inertes decódigoHTMLquesólosonacDvadascuandoserenderizaelcomponente
HTMLImports
Ofreceunmodelodemodulariza-ción basado en la posibilidad deincluir ficheros de código HTMLdentrodeotrosficherosHTML
CustomElements
Ofreceunmodelodeextensibilidadque permite a los desarrolladoresdefinir sus propias eDquetas oredefinir semánDcamente laseDquetasdelestándarDOM
@javiervelezreye14
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
Sinmásinfraestructuradesoporte,losiden1ficadoresJSyCSSu1lizadosinternamentedentrodecadacomponentepodríancolisionarconlosusadosdentrodelapáginahuéspedoenotroscomponentes residentes. Es necesario proporcionar unmecanismode encapsulamiento queaíslecadainstanciadecomponentedelrestodeinstanciasydelapropiapágina.
ElProblema
<button id='btn'> <button/>
index.html
<button id='btn'> <button/>
Click
Click
document.querySelector ('#btn') .on ('click', function () { ... });
document.querySelector ('#btn') .on ('click', function () { ... });
SiusamosdosinstanciasdelmismoDpo de componente los códigosverDdosalapáginaanfitrionaparacada instancia serán idénDcos ycolisionaránentresíyaqueseusanidenDficadoreshomónimos
ColisióndeIdenIficadores
@javiervelezreye15
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
Esnecesario,portanto,proporcionarunmecanismodeencapsulaciónqueaíslecadainstanciade componente del resto de instancias y de la propia página. desde un punto de vistaconceptual, es posible clasificar los 1pos de aislamiento necesarios en tres categoríasdiferentesdeacuerdoalarelacióndeloselementosenpotencialconflicto.
LaSolución
ContenidoTipoA
.foo
.bar
ContenidoTipoA
.foo
.bar
ContenidoTipoB
.baz
.foo
ContenidoTipoA
.foo
.bar
index.html index.html
ContenidoTipoA
.foo
.bar
.foo
index.html
AislamientoentrecomponentesAislamientoconlapáginaanfitriona
Aislamientoentreinstancias
@javiervelezreye16
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
El proceso de encapsulación consiste, esencialmente, en generar nuevos árboles DOMparaalbergarloscontenidosdecadainstanciadecomponenteWebyvincularlosaciertosnodosdelapáginaanfitriona.Deestamaneraseconsiguequedichoscontenidosresidanenunespaciodenombresexclusivoyaisladodeldelosdemásydeldelapropiapágina.
ShadowDOM&ShadowHOST
LightDOM
.shadowRoot
ShadowDOM
ShadowHostEl ShadowHost, que puede sercualquier eDqueta HTML, es unnodo de la página anfitrionaque vincula una instancia decomponenteadichapágina
ShadowRootEl Shadow Root es un nodode Dpo DocumentFragmentque se corresponde con laraíz del árbol DOM delcontenidoencapsuladoporelcomponente
.host
Componente
@javiervelezreye17
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
El proceso de encapsulación consiste, esencialmente, en generar nuevos árboles DOMparaalbergarloscontenidosdecadainstanciadecomponenteWebyvincularlosaciertosnodosdelapáginaanfitriona.Deestamaneraseconsiguequedichoscontenidosresidanenunespaciodenombresexclusivoyaisladodeldelosdemásydeldelapropiapágina.
ShadowDOM&ShadowHOST
LightDOM
.shadowRoot
ShadowDOM
.host
Componente1
En los navegadores sin soporte acomponentes web se aplica elalgoritmoderenderizadohabitual.Como el shadow DOM no esaccesible por este algoritmo, elcomponente no se renderiza y seconDnúaporelrecorridohabitual
Renderizadonormal
1
2
Cuandoel soporteacomponentesweb está acDvo, el algoritmo derenderizado discrimina entrenodos normales y nodos shadowhost. En éstos úlDmos, deriva elproceso de renderizado paramostrar el contenido del shadowDOMmientraselLightDOMnosemuestra
Renderizadoshadow
2
@javiervelezreye18
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
Desde la especificación de ShadowDOM, la únicamanera de crear esta estructura dual decontenidos es a través de JavaScript. Para ello, se ex1ende el nodo Element con un nuevométodo para la creación de nodos Shadow Root que se vinculan automá1camente al nodosobreelqueseaplicanconvir1éndoloasíenunShadowHost.
ShadowDOM&ShadowHOST
<div id="myHost"> contenido del light dom </div>
<script> var host = document.querySelector('#myHost'); var root = host.createShadowRoot(); root.innerHTML = "contenido del Shadow DOM"; </script>
Cualquier Dpo de nodo DOM puede serconverDdo en Shadow Host. Para ello esnecesario uDlizar alguno de losmecanismosde referencia disponibles en HTML quepermitan seleccionar el nodo desdeJavaScript
ShadowHost
Primero se localiza el nodo que hará deanfitrión y se convierte en shadow hostcreandoenélunnodoshadowroot.DespuéssóloquedainyectarcontenidoHTMLenestenuevo nodo por cualquier mecanismoestándarparacrearelShadowDOM
ShadowRoot
@javiervelezreye19
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
Esposibledefinirmúl1plesárbolesenlasombraorganizadosporcapas.ElShadowHostsiguereteniendo un enlace al ShadowRoot más reciente. Desde éste se puede recorrersucesivamente cadaShadowDOMa travésdeenlacesolderShadowRoot. Yporúl1mo, cadaShadowRootdisponedeunareferenciaalShadowHost.
ShadowDOMPorCapas
LightDOM
PáginaHuésped
.olderShadowRoot
.host
.host
.host
.shadowRoot
.olderShadowRoot
YoungestShadowDOM
OldestShadowDOM
Desde cada Shadow Root sepuedeaccederalanterioratravésde enlaces olderShadowRoot aexcepcióndelúlDmoqueDeneunvalornullenesteenlace
Cada Shadow Root manDeneunareferenciadirecta(host)alShadow Host que ancla elcomponente a la páginaanfitriona
ShadowDOMporCapas
ReferenciaalShadowHost
Recorridoporlacadenadecapas
@javiervelezreye20
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
Para crear una estructura mul1capa simplemente es necesario invocar repe1damente elmétodocreateShadowRootsobreelnodoHost.CadavezquesellamaaestemétodosecreaunnuevoShadowRootqueseestablececomoprimeracapadeacuerdoa laarquitecturadeenlacesanterior.UnavezquesecreaunenlaceShadowRootesimposibleeliminarlo.
ShadowDOMPorCapas
<div id="myHost"> contenido del light dom </div>
<script> var host = document.querySelector('#myHost'); var root1 = host.createShadowRoot(); var root2 = host.createShadowRoot(); var root3 = host.createShadowRoot(); root1.innerHTML = ... root2.innerHTML = ... root3.innerHTML = ... </script>
Igual que antes es necesario hacer uso dealguno de los mecanismos de referencia deHTMLparapoderaccederalnodoDOMquehará de Shadow Host desde el códigoJavaScript
ShadowHost
Cada vez que se invoca al métodocreateShadowRoot se genera un nuevoShadow DOM que se establece comoprimera capa dentro de la arquitectura deenlaces
ShadowRoots
@javiervelezreye21
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
Los componentesWebpueden construirse a través deprocesos de anidamientodemaneraqueuncomponenteinternopuedahospedarsedentrodelShadowDOMdeotrocomponenteexterno. El papel del modelo de encapsulación en este 1po de escenarios de anidamientoman1enelagaranbadelaausenciadecolisiónparacadacomponentepar1cipante.
ShadowDOMAnidado
.shadowRoot
.host
C.Externo
C.Interno
.host
.shadowRoot
El componente externo actúacomo anfitrión respecto alcomponenteinterno
El componente interno actúacomo huésped en la relaciónde anidamiento con e lcomponenteexterno
Rolanfitrión
Rolhuésped
@javiervelezreye22
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
El proceso de creación de componentes anidados requiere iden1ficar el nodo Host delcomponente externo y crear un Shadow Root donde se inyecta un contenido HTML. Estecontenido incluye todo el cuerpo del Light DOM del componente interno. Finalmente esprecisocrearunShadowRootparaelcomponenteinternoeinyectarlesucontenidoHTML.
ShadowDOMAnidado
antes del componente externo <div id="outerHost"> ... </div> después del componente externo
<script> var outerHost = document.querySelector('#outerHost'); var outerRoot = outerHost.createShadowRoot(); outerRoot.innerHTML = 'antes del componente interno' + ' <div id="innerHost"> Light DOM interno </div> ' + 'después del componente interno'; var innerHost = outerRoot.querySelector('#innerHost'); var innerRoot = innerHost.createShadowRoot(); innerRoot.innerHTML = 'en el componente interno'; </script>
Se idénDca el nodo que servirá de anfitriónpara hospedar el componente externo ypoderaccederlodesdeJavaScript
Componenteexterno
Primero se crea el Shadow Root del compo-nente externo y se inyectan los contenidos desuShadowDOMqueencapsulanalLightDOMdel componente interno. Después se crea elShadowRoot del componente interno y se leinyectasucontenidoHTML
AnidamientodecomponenteInterno
@javiervelezreye23
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
Encomponentes simplesel ShadowDOMpuede requeriraccederde formadiscrecionala lainformación de configuración contenida dentro del Light DOM para que forme parte delproceso de rendering del componente. Gracias a este mecanismo se consigue adaptar elaspectoycomportamientodecadainstanciadecomponenteasucontextodeuso.
DistribuciónDeContenidos
LightDOM ShadowDOM
Componente El shadow DOM podría necesitarseacceder de forma discrecional apartes de la información Light DOMpara arDcular su renderizado.Necesitamos un mecanismo dereferencia de información desde elShadowDOMalLightDOM
Referenciadeinformación
ElLightDOMconDeneinforma-ciónsemánDca sobre la configura-cióndel componente que permiteadaptar su aspecto y comporta-miento
Informacióndeconfiguración
.shadowRoot
?
@javiervelezreye24
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
Encomponentes simplesel ShadowDOMpuede requeriraccederde formadiscrecionala lainformación de configuración contenida dentro del Light DOM para que forme parte delproceso de rendering del componente. Gracias a este mecanismo se consigue adaptar elaspectoycomportamientodecadainstanciadecomponenteasucontextodeuso.
DistribuciónDeContenidos
LightDOM ShadowDOM
Componente
El shadowDOM podría necesitarseacceder de forma discrecional apartesde
PuntodeInsercióndeContenido
SedicequeelconjuntodenodosdelLightDOMquesevenafectadospore l p roceso de se lecc ión sedistribuyen, durante el renderiza-do,alpuntodeinsercióndentrodelShadowDOM
NodosDistribuidos
.shadowRoot
<content select='…'>
@javiervelezreye25
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
EldiseñodelLightDOMdebeanotarsesemán1camentedemaneraapropiadaparaquepuedareferirsemedianteexpresionesdeselecciónCSSapar1rdelase1quetascontentquefigurandentrodelShadowDOM.Hastaciertopuntopuedeconsiderarsequelase1quetascontentsonunmecanismodeinyecciónparamétricadelosvaloresmantenidosporelLightDOM.
DistribuciónDeContenidos
<div class="product"> <div class="type">Food</div> <div class="name">Pears</div> </div>
<script> var host = document.querySelector('#myHost'); var root = host.createShadowRoot(); root.innerHTML = '<ul>' + ' <li>Type: <content select=".type"></content></li>' + ' <li>Name: <content select=".name"></content></li>' + ' <li>Amount: <content select=".amount">1</content></li>' + '</ul>' </script>
ElLightDOMconDenelainformaciónquevaa ser referida desde los puntos de insercióndecontenidopresentesenelShadowDOM
LightDOM
El Shadow DOM conDene puntos dei n s e r c i ón pa ra r e f e r i r a l ainformacióndelLightDOM
ShadowDOM&ContentSelect
@javiervelezreye26
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
En los escenarios de componentes construidos por capas, es necesario, adicionalmente a loanterior, disponerdeunmecanismoquepermita accederdesde cada capaa la informacióncontenida en la inmediatamente inferior. De estamanera, cada capa se concibe como unadecoraciónquecontribuyeaenriquecerelcontenidodelaque1eneporencima.
DistribuciónDeContenidosEnLaSombra
Es necesario un mecanismo deacceso a los contenidos en lasombra que permita a una caparecuperarelcontenidomantenidoporlacapainferior
Desde cada capa se puedeseguiraccediendonormalmentea los contenidos en el LightDOM por medio de la eDquetacontent
LightDOM
AccesoalaCapaInferior
LightDOM
.shadowRoot
ShadowDOMporCapas
.olderShadowRoot
.olderShadowRoot
Nododecontenidoencapa Puntodeinserciónenlasombra
<content> <shadow>
@javiervelezreye27
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeEncapsulamiento.ShadowDOM
Demanerasimilaraladistribucióndecontenidosexisteunae1quetashadowquepermiteaunshadow DOM capturar todo el contenido del del shadow DOM que se encuentrainmediatamente por debajo de él en la jerarquía de capas. Esta e1queta no dispone sinembargodefiltroselect.
DistribuciónDeContenidosEnLaSombra
<script> ... root1.innerHTML = 'Esta capa está oculta'; root2.innerHTML = 'D. <content select…'; root3.innerHTML = '<div class=".box">' + ' <shadow></shadow>' + '</div>'; </script>
Las capas que no tuvieran unareferencia <shadow> desde capassuperiores no serían incluidas en elprocesoderenderizado
ExistenCapasOcultas
@javiervelezreye28
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeRenderizado.HTMLTemplates
Noespocofrecuenteencontrarsituacionesenlasqueesnecesarioinstanciardosocurrenciasdiferentes de un mismo componente sobre la misma página, aunque sea con light DOMdiferentes.¿Pomopodemosevitarel trabajode reescribirel shadowDOMenteroparacadainstanciadeformaeficazysegura?
PlanRllasInertesYAcRvaciónDeCódigoPorClonación
PáginaHuésped
<div id=‘A-1’>
</div>
<div id=‘A-2’>
</div>
Elcontenidodelosdossubárbolesshadowes elmismo puesto que ambas eDquetasresponden a instancias disDntas (-1 y -2)delmismocomponenteA
ShadowDOMidénIcos
Cada instancia sin embargo conDene unoscontenidos semánDcos disDntos dentro delsubárbol light que sirven para configurar lamismadeformaparDcular
LightDOMdiferentes
@javiervelezreye29
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeRenderizado.HTMLTemplates
Noespocofrecuenteencontrarsituacionesenlasqueesnecesarioinstanciardosocurrenciasdiferentes de un mismo componente sobre la misma página, aunque sea con light DOMdiferentes.¿Pomopodemosevitarel trabajode reescribirel shadowDOMenteroparacadainstanciadeformaeficazysegura?
PlanRllasInertesYAcRvaciónDeCódigoPorClonación
<template id="news"> <img src=""> <div class="body"></div> </template> <div id="new-1"></div> <div id="new-2"></div>
<script> function createNew(container, image, body) { var root = document.querySelector(container).createShadowRoot(); var template = document.querySelection("#news").content; template.querySelector("img").scr = image; template.querySelector(".body").textContent = body; root.appendChild(template.content.cloneNode(true)); } createNew('#new-1', 'imagen1.png', 'noticia 1'); createNew('#new-2', 'imagen2.png', 'noticia 2'); </script>
El código de la planDlla se procesapero la carga de recursos no seproducehastalaacDvación
PlanIllaInerte
La acDvación de una planDllaconsiste en un proceso de clonacióndel nodo DOM que manDene loscontenidos
AcIvación
@javiervelezreye30
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeExtensión.CustomTags
Ahoraque tenemos losmecanismosnecesarios para definir y encapsular comportamiento ylógica de presentación personalizada necesitamos una manera de referirlo nominalmentedentrodenuestrapáginaWebenformadee1quetaspersonalizadas.Estopermitedis1nguirloscomponentesdelase1quetasestándarloqueaumentalalegibilidaddelapágina.
CreaciónDeERquetasPersonalizadas.CustomTags
Los nombres de las eDquetas personalizadas debentener al menos un guión en el nodeName paradiferenciarlasdelaseDquetasestándar.
Regla1.Nombresconalmenosunguión
<wc-calendar> ... </wc-calendar>
No pueden uDlizarse como nombres de eDquetaspersonalizadascualquieradelascadenasconguiónqueseenumeranaconDnuación.
Regla2.Nombresreservados
annotation-xml color-profile font-face font-face-src font-face-uri font-face-format font-face-
name missing-glyph
... <wc-calendar> <wc-calendar-day>12</wc-calendar-day> <wc-calendar-month>06</wc-calendar-month> <wc-calendar-year>2014</wc-calendar-year> </wc-calendar> ...
@javiervelezreye31
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeExtensión.CustomTags
Debemospreocuparnos,porunlado,deregistrarcadacomponenteconstruidocomounnuevo1po de e1queta dentro del sistema de e1quetas del navegador y después de instanciarcomponentestantodesdeellenguajedemarcadocomoatravésdeJS.
CreaciónDeERquetasPersonalizadas.CustomTags
var p = Object.create(HTMLElement.prototype); p.foo = function (){...}; p.bar = 7; var Foo = document.registerElement( 'wc-foo', {prototype: p});
<wc-foo id="a"> ... </wc-foo> <wc-foo id="b"> ... </wc-foo>
var a = new Foo (); var b = document.createElement('wc-foo'); document.body.appendChild (a); document.body.appendChild (b);
RegistrodeunComponente InstanciacióndeunComponente
Primero se crea el protoDpo delcomponente y se registra como unanueva eDqueta con la funciónregisterElement
Creación
Una vez creado el componente yregistrado comounanueva eDquetase puede usar como cualquier otraeDquetaestándar
Uso
@javiervelezreye32
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeExtensión.CustomTags
Es posible extender las propias e1quetas del estándar HTML para generar variantes queincluyannuevocomportamientoológicapresentacionalcuandoserendericen.Estase1quetasman1enen, naturalmente, el nombre de la e1queta a la que ex1enden pero incluyen uncalificadorisparaindicaralnavegadordequesetratadeunavariantedis1nta.
ExtensióndeERquetasEstándar.ExtendedElementTypes
... <button id="btn" is="fancy-button"> Ok </button> <p is="lorem-ipsum"><p> ... <script> var btn = document.querySelector(‘#btn’); btn.addEventListener('click', function(e){ ... }); </script>
Las eDquetas del estándar se exDenden convariantes cualificadas nominalmente dentro delatributois.EstaseDquetasmanDenenelnombre,métodos y atributos de la eDqueta de la quederivan pero pueden sobrescribir o agregarnuevascapacidades
ExtensióndeEIquetasEstándar
La nueva variante de botón incluye, porherencia todos los atributos, métodos ymodelo de eventos que Dene la eDquetabasedelaquederiva
HerenciadeCapacidades
@javiervelezreye33
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeExtensión.CustomTags
De forma similar al casoanterior, comenzaremospor registrar cada componente construidocomo una variante que ex1ende una e1queta del estándar y después nos ocuparemos deinstanciarcomponentestantodesdeellenguajedemarcadocomoatravésdeJS.
ExtensióndeERquetasEstándar.ExtendedElementTypes
var p = Object.create(HTMLButtonElement.prototype); p.foo = function (){...}; p.bar = 7; var FancyButton = document.registerElement( 'fancy-button', {extends: 'button', prototype: p});
<button is="fancy-button" id="a"> Ok </button> <button is="fancy-button" id="b"> Ok </button>
var a = new FancyButton (); var b = document.createElement ('fancy-button'); document.body.appendChild (a); document.body.appendChild (b);
RegistrodeunComponente InstanciacióndeunComponente
En este caso la creación requierecrear un protoDpo que hereda delprotoDpoHTMLBuionElement
Creación
Adiferenciade laseDquetaspersonalizadas,aquí semanDene el nombre de la eDqueta y se cualificasemánDcamente con el atributo is para favorecer eldescubrimientoSEO
Uso
@javiervelezreye34
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeModularización.HTMLImports
La implementacióndeuncomponente incluyeuncódigodeplan1lla inerte,especificacionesdees1loynopocalógicadescrip1ngparaespecificarelmodelodecomportamiento.Parecenecesario disponer de un mecanismo de modularización que permita incluir todo esecontenidoenunficherodeíndiceaparteHTMLquepuedaimportartealapáginahuésped.
ImportacióndedocumentosHTML
<!doctype html> <html lang="es"> <head> <meta charset="utf-8"> <script src="webcomponents.js"></script> <script src="polymer.js"></script> <link rel="import" href="my-lib.html"> </head> <body> ... </body> </html>
<!doctype html> <html lang="es"> <head> <link rel="import" href="tag-1.html"> <link rel="import" href="tag-2.html"> <link rel="stylesheet" href="style-1.html"> <link rel="stylesheet" href="style-2.html"> <script src="script-1.js"></script> <script src="script-2.js"></script> </head> <body> <!– codigo del componente --> ... </body> </html>
Index.html My-lib.html
style-2.cssstyle-1.css
script-2.jsscript-1.js
tag-2.htmltag-1.html
@javiervelezreye35
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeModularización.HTMLImports
La implementacióndeuncomponente incluyeuncódigodeplan1lla inerte,especificacionesdees1loynopocalógicadescrip1ngparaespecificarelmodelodecomportamiento.Parecenecesario disponer de un mecanismo de modularización que permita incluir todo esecontenidoenunficherodeíndiceaparteHTMLquepuedaimportartealapáginahuésped.
AccesoalRecursoImportadoyalaPáginaAnfitriona
<!doctype html> <html lang="es"> <head> ... <link rel="import" href="file.html"> </head> <body> ... </body> </html>
<!doctype html> <html lang="es"> ... <body> <script> var f = document.currentScript.ownerDocument; var h = document; // f refiere a este documento HTML // h refiere a la página huésped </script> </body> </html>
Index.html file.html
I.ContextodeAnfitrión
El contexto en el que se evalúan losscriptdentrodeunapáginaimportadaeseldelapáginaanfitriona
II.EvaluaciónSecuencial
Lasimportacionessonnobloqueantes.Sinembargo los script dentro de la páginaimportadaseejecutanenorden
III.EvaluaciónÚnica
Las importaciones desde una mismaURLsonprocesadassólounavezconloquesusscriptsóloseejecutanunavez
@javiervelezreye36
EstándaresEnComponentesWebElProyectoPolymer
ModeloDeModularización.HTMLImports
Para controlar los procesos de carga derecursosdedocumentosHTML importadosmediante la direc1va import se puedeninyectarmanejadores a eventos de éxito yerror.
EventosdeCargayError
<script async> function handleLoad(e) { console.log(‘Loaded import:’ + e.target.href); } function handleError(e) { console.log(‘Error loading import:’ + e.target.href); } </script> <link rel=“import” href=“file.html” onload=“handleLoad(event)” onerror=“handleError(event)”>
<head> <link id=“foo-link” rel=“import” href=“wc-foo.html”> </head> <body> ... <script> var link = document.querySelector(‘#foo-link’); var content = link.import; var el = content.querySelector(‘...’); ... </script> </body>
El desarrollador 1ene la oportunidad de capturarprogramá1camente el contenido importadomedianteunadirec1va importyoperarsobreélaconveniencia.
ManipulaciónDeContenidos
JavierVélezReyes@javiervelezreye
3ElFrameworkPolymer
§ ModelodeComponentesPolymer§ ExtensionesalModelodePlan1llas§ ExtensionesalModelodeComponente
Introd
ucción
ElProyectoPo
lymer
@javiervelezreye38
ElFrameworkPolymerElProyectoPolymer
ElFrameworkPolymer Google ha desarrollado, por encima de la implementación de los
estándaresdeComponentesWeb,unframeworkdirigidoasimplificarlos procesos de desarrollo con esta tecnología. A lo largo de estecapítuloveremoscualessonsusventajaspar1culares.
HTMLTemplates
Ofrece unmodelo de construcción basadoen planDllas inertes de código HTML quesólo son acDvadas cuando se renderiza elcomponente
CustomElements
Ofrece un modelo de extensibilidad quepermite a los desarrolladores definir susp r o p i a s e D q u e t a s o r e d e fi n i rsemánDcamentelaseDquetasdelestándarDOM
ModelodeComponentePolymer
DataBindingPlan1llasDinámicas
AtributosCiclodeVidaObservers
@javiervelezreye39
ElFrameworkPolymerElProyectoPolymer
ModeloDeComponentesDePolymer
LadefinicióndeComponentesWebsinlógicafuncionalconPolymeresunejerciciocompletamentedeclara1vomediantelae1quetapolymer-elementyelmodificadornoscript.
ComponentesWebSinLógica
<script> var host = document.querySelector('#myHost'); var root = host.createShadowRoot(); root.innerHTML = "contenido del Shadow DOM"; </script>
Polymer
WebComponents
<polymer-element name="profile-card" noscript> <template>
...
</template>
</polymer-element>
El atributo noscript incluye una lógicade configuración por defecto para loscompo-nentessinlógicafuncional
@javiervelezreye40
ElFrameworkPolymerElProyectoPolymer
ModeloDeComponentesDePolymer
Cuandoelcomponente1ene lógica funcionalseañadeunscriptquesevinculaautomá1camentea laplan1llaHTMLadjuntasinu1lizarelatributonoscript.
ComponentesWebConLógica
<script> var host = document.querySelector('#myHost'); var root = host.createShadowRoot(); root.innerHTML = "contenido del Shadow DOM"; </script>
Polymer
WebComponents
<polymer-element name="profile-card"> <template>
...
</template>
<script>
...
</script>
</polymer-element>
Los componentes con lógica funcionalañadenuna eDqueta script que operasobre los contenidos de la planDllaadjunta
@javiervelezreye41
ElFrameworkPolymerElProyectoPolymer
ModeloDeComponentesDePolymer
Para definir un Componente Web como extensión deotrocomponenteodeunae1quetaestándarbastaconusarelpardeatributosextends/is.
ExtensiónDeComponentesWeb
var p = Object.create(HTMLButtonElement.prototype); var FancyButton = document.registerElement(
'fancy-button',
{extends: 'button', prototype: p});
Polymer
WebComponents
<polymer-element name="fancy-button" extends="button"> ...
</polymer-element>
<button is="fancy-button"> ... </button>
Para declarar un componente comoextensióndeotroseuDlizaelatributoextendsenladefinicióndelmismo
Después para su uso se uDliza laeDqueta del padre y se cualificasemánDcamentealcomponenteconelatributois
@javiervelezreye42
ElFrameworkPolymerElProyectoPolymer
ExtensionesAlModeloDeCustomElements
La lógica de comportamiento del componente incluyeunmodelodedatos,unconjuntodemétodosdeciclodevidayunmanejadordecambiosdelosatributos.
Atributos&CiclodeVida
<polymer-element name="wc-card" attributes="name age"> ... <script> Polymer ('wc-card', { this.name,
this.age: 18,
created : function () {},
ready : function () {},
attacched : function () {}, domReady : function () {},
detached : function () {},
...
</script>
</polymer-element>
El modelo de datos se soporta aparDrdeladeclaracióndevariableslocales. Ojo los Dpos primiDvosoperananiveldeinstanciamientrasquelosobjetosaniveldeprotoDpo
Los manejadores del ciclo devida permiten incluir códigoque t r a t a l o s e ven to svinculados a la creación ydestruccióndelainstancia
@javiervelezreye43
ElFrameworkPolymerElProyectoPolymer
ExtensionesAlModeloDeCustomElements
La lógica de comportamiento del componente incluyeunmodelodedatos,unconjuntodemétodosdeciclodevidayunmanejadordecambiosdelosatributos.
Métodos&Observadores
<polymer-element name="wc-card" attributes="name age"> ... <script> ... adult : function (){ return this.age > 18 },
name : function (name){ ... },
age : function (age){ ... },
attributeChanged : function (att, ov, nv){},
nameChanged : function (ovalue, nvalue){}, ageChanged : function (ovalue, nvalue){}
});
</script>
</polymer-element>
ExistendosformasparagesDonarelcambiodevalordelosatributos.Sepuede usar el método genéDcoaiributeChanged o definirmaneja-doresdecambiodedicados
Los métodos de negocio seincluyen tal cual al protoDpodelcomponentedefinido
@javiervelezreye44
ElFrameworkPolymerElProyectoPolymer
ExtensionesAlModeloDePlanRllas
Polymer vincula cada referencia en elcontenidodelasplan1llasHTMLalmodelodedatos subyacentedemaneraque los cambiossepropaganautomá1camente.
DataBindingBidireccional<polymer-element name="wc-card" attributes="name age"> <template> Hola, mi nombre es {{ name }} y tengo {{ age }} años </template> <script> Polymer ('wc-card') { this.name,
this.age: 18, ... }
</script>
</polymer-element>
LosvaloresdelosatributosdelmodelodedatossepropaganalavistademaneraautomáDca
Asimismo, las referencias sobre elementos deedición HTML que causan cambios en losatributos provocan actualizaciones en elmodelosubyacente.
<polymer-element name="wc-card" attributes="name age"> <template> Hola, mi nombre es {{ name }} y tengo {{ age }} años </template> <script> Polymer ('wc-card') { this.name,
this.age: 18, ... }
</script>
</polymer-element>
Recíprocamente los cambiossobre los atributos que seproducen sobre la v istaa c t u a l i z a n e l m o d e l osubyacente
@javiervelezreye45
ElFrameworkPolymerElProyectoPolymer
ExtensionesAlModeloDePlanRllas
Polymerex1ende lae1queta templateparadotarladecapacidades de renderizado dinámico. A con1nuacióndescribimoslasprincipalescapacidades.
PlanRllasDinámicas
EnlaceaTexto
<p>{{user.name}}</p>
EnlaceaAtributo
<img src="{{image}}" alt="imagen">
ManejadordeEventoEstándar
<button on-click="{{doClick}}"> Ok </button>
EnlaceaAtributoCondicional
<div class="card" hidden?="{{show}}"
ManejadordeEventodeNegocio
<div id="my-component" on-done="{{doAlarm}}"> ... </div>
EnlaceconOperadorCondicional
<template repeat="{{item, i in items}}"> <div class="{{(i%2==0)? 'on' : 'off'}}"> {{item}} </div> </template>
@javiervelezreye46
ElFrameworkPolymerElProyectoPolymer
ExtensionesAlModeloDePlanRllas
Polymerex1ende lae1queta templateparadotarladecapacidades de renderizado dinámico. A con1nuacióndescribimoslasprincipalescapacidades.
PlanRllasDinámicas
PlanIlladeEnlacedeDatos
<template bind="{{person as me}}"> {{me.name}} – {{me.twitter}} </template>
PlanIllaCondicional
<template bind="..." if="truthy"> {{me.name}} – {{me.twitter}} </template>
PlanIllaIteraIva
<template repeat="{{item in items}}"> <li>{{item}}</li> </template>
PlanIllasReferidas&Anidadas
<template repeat="i in items" id="t"> <li>{{i}} <ul> <template repeat="{{i.hijos}}" ref="t"> </template> </ul> </template> ... <template bind ref="t"> </template>
PlanIllasAnidada
<template repeat="{{u in users}}"> <template repeat="{{i in u.items}}"> <li>{{i}}</li> </template </template>
JavierVélezReyes@javiervelezreye
4EcosistemadeComponentesdePolymer
§ ComponentesWebDePolymer§ CoreElements§ PaperElements§ DesarrollodeAplica1vosBasadosenComponentes
Introd
ucción
ElProyectoPo
lymer
@javiervelezreye48
EcosistemadeComponentesdePolymerElProyectoPolymer
ComponentesWebDePolymer Google ha desarrollado, por encima de la implementación de los
estándaresdeComponentesWeb,unframeworkdirigidoasimplificarlos procesos de desarrollo con esta tecnología. A lo largo de estecapítuloveremoscualessonsusventajaspar1culares.
CoreElementsLoscomponentescore-elementdePolymerdan soporte a capacidades nuclearesrelacionadasconlagesDóndelalógicadepresentacióndecomponentesWeb
PaperElementsLos componentes paper-element dePolymerseencargandearDcularelmodelodepresentaciónbasadoenMaterialDesignpropiodeGoogle
@javiervelezreye49
EcosistemadeComponentesdePolymerElProyectoPolymer
CoreElements
Con Polymer es posible crear aplicaciones porcomposicióndecomponentesWeb.Coreheaderpaneles uncontenedorsimpleconunaseccióndecabecerayotradecontenido.
CoreHeaderPanel
CoreDrawerPanelEl componente core-header-panel es uncontenedor responsive que combina un menúlateral deslizante con un área de contenidoprincipal.
<core-header-panel mode="scroll" flex> <core-toolbar> <core-icon-button icon="menu"> </core-icon-button> <div>MY APP</div> </core-toolbar> <div class="content">...</div> </core-header-panel>
MY APP
<core-drawer-panel> <div drawer> Drawer panel... </div> <div main> Main panel... </div> </core-drawer-panel>
@javiervelezreye50
EcosistemadeComponentesdePolymerElProyectoPolymer
PaperElements
Polymer también ofrece una amplia librería decomponentes que implementan las normas dees1lodeMaterialDesign.Paper-checkboxesunejemplodeello.
PaperCheckbox
PaperInputPaper-inputesuncomponentequesus1tuyealae1quetaestándar inputdeHTMLofreciendouncomportamientomásdinámicoymayor riquezaenlaexperienciadeusuario.
<paper-checkbox> ... </paper-checkbox>
<paper-input label="Nombre"> ... </paper-input>
@javiervelezreye51
EcosistemadeComponentesdePolymerElProyectoPolymer
DesarrollodeAplicaRvosBasadosenComponentes
Parámetros de configuración
wc-bus
<Timeline <zoom >next >previous >go
>zoom-in >zoom-out
zoom-in, zoom-out,
go go
zoom-in, zoom-out
wc-slideswc-video
wc-speech
EldesarrollodeaplicacionesorientadasaComponentesWebrequieredeciertainfraestructurade control dedicada a ar1cular procesos de coordinación y orquestación entre loscomponentes cons1tuyentes. Esta lógica puede encapsularse en componentes de controlreu1lizables.Veamosunejemplo.
@javiervelezreye52
PreguntasElProyectoPolymer
JavierVélezReyes@javiervelezreye
ElFrameworkPolymerEstándaresde
ComponentesWebElEcosistemadeComponentes
JavierVélezReyes@javiervelezreye
ElProyectoPolymer
ProgramaciónOrientadaaComponentesWeb
Febrero2015