Sie sind auf Seite 1von 93

Manual de Polymer 2

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 1 de 93
Manual de Polymer 2

Introducción: Manual de Polymer 2

Este es el manual de Polymer 2, la librería para el desarrollo con el estándar de los Web Components.
Polymer es una librería creada por Google para facilitar el trabajo en el desarrollo de componentes y
aplicaciones complejas.

Ahora que el estándar Web Components V1 es una realidad y el soporte en navegadores está prácticamente
generalizado, Polymer 2 se ha reformulado completamente para ofrecer una manera de desarrollar más ágil
y más cercana al estándar.

En Polymer 2 prima el desarrollo nativo, con Javascript estándar, lo que ofrece una mayor velocidad y
menor peso de las aplicaciones, ya que se apoya en todo lo que la plataforma web nos ofrece a los
desarrolladores. Tanto es así que la librería ocupa solo 11K en navegadores que no necesiten la carga de
polyfills.

En este Manual de Polymer 2 nos ponemos manos a la obra para acercar la mejor librería basada en Web
Components, capaz de extraer lo mejor del estándar y permitir una mayor velocidad y comodidad de
desarrollo. Explicaremos cómo se desarrollan componentes basados en Polymer 2 y cómo usar la
inacabable biblioteca de elementos ya listos para el desarrollo de aplicaciones complejas.

Encuentras este manual online en:


http://desarrolloweb.com/manuales/manual-polymer-2.html

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 2 de 93
Manual de Polymer 2

Autores del manual

Las siguientes personas han participado como autores escribiendo artículos de este manual.

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online


EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997,
transformando su hobby en su trabajo.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 3 de 93
Manual de Polymer 2

Primeros pasos en el desarrollo con


Polymer 2

Comenzamos con una serie de artículos que nos aproximarán al desarrollo de componentes con la librería
de Google. Explicaremos qué es Polymer y en qué se basa para ofrecer al desarrollador quizás la mejor
plataforma para la creación de componentes y aplicaciones web.

Nuestro objetivo fundamental en estos primeros artículos es explicar fundamentos del estándar de los Web
Components V1, que permite el desarrollo de elementos personalizados con los cuales extender el HTML y
aportar nuevas funcionalidades a los navegadores, que podrán ser compartidas y reutilizables de manera
general. Luego veremos cómo el desarrollo con Web Components y el desarrollo con Polymer 2 pueden ser
muy similares, ya que la librería de Google se basa directamente en el estándar. Por último conoceremos
cómo es un componente de Polymer, sus diferentes partes y cómo usar el toolbox disponible en Polymer 2
para facilitarnos el día a día en el desarrollo de aplicaciones web.

Polymer 2.0 introducción


Qué es Polymer 2.0 y por qué representa una revolución, junto con los Web Components V1, en el
mundo del desarrollo web frontend.

En DesarrolloWeb.com nos hemos subido al tren de los Web Components porque creemos que el
desarrollo basado en estándares abiertos es la mejor garantía para el futuro. Desde hace casi dos años
venimos ofreciendo manuales para lanzarse a este mundo y en ese sentido ya hemos publicado un Manual
de Web Components y el Manual de Polymer. Sin embargo, en esta ocasión tenemos que empezar de nuevo
porque la tecnología ha tenido importantes mejoras que nos obligan a actualizarnos.

Para introducirnos en esta ocasión en el mundo de los Web Components vamos a usar la librería Polymer 2,
cuyo lanzamiento ha sido realizado hace poco. Es una tecnología que aprovecha todas las ventajas de los
Web Components y nos hace más fácil el desarrollo de componentes web encapsulados y reutilizables.

En este artículo pretendemos ofrecer una introducción a Polymer 2 y los Web Components V1, para ir
abordando una materia que sin duda está revolucionando el desarrollo frontend. En los próximos artículos
nos pondremos manos a la obra, ya con código, con el que poder experimentar todas estas novedades.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 4 de 93
Manual de Polymer 2

Web Components V1

Los Web Components son un estándar abierto que ha sido impulsado principalmente por Google y su
navegador Chrome. Sin embargo, su adopción en el total del abanico de navegadores ha sido más lenta de
lo esperado inicialmente, ya que involucra a muchas empresas que tienen maneras diferentes de entender el
desarrollo para la web.

La primera especificación de Web Components se nombró como V0 (Versión cero) y resultó un gran
avance, pero no llegó a estar incorporada de manera generalizada. Es la que en su día explicamos en el
Manual de Web Components. Básicamente el concepto sigue siendo el mismo, por lo que si no sabes qué
son los componentes es interesante la lectura al menos de los primeros artículos en los que se repasan los
conceptos principales y las especificaciones relacionadas con la tecnología.

Nota: Por si alguien no lo sabe todavía y para resumir rápidamente de manera simplificada, los Web
Components nos permiten crear nuevos elementos, como etiquetas HTML, que extienden el
comportamiento de los navegadores. Podemos tener elementos para hacer cualquier cosa, como
interfaces de usuario no disponibles en el HTML estándar o componentes que ofrecen funcionalidad de
una aplicación completa. Los componentes tienen la gracia de poder reutilizarse y compartirse
fácilmente, con lo que los desarrolladores pueden extender la web y llevarla a los límites de la
imaginación de cada uno. Web Components nos ofrece una manera estándar de extender las
funcionalidades de los navegadores, de manera que un desarrollo de una persona puede servir para toda
la comunidad y ser compatible en cualquier navegador, de escritorio o móvil. Para quien venga del
desarrollo con otros frameworks y librerías, como React, Angular, VueJS, etc., Web Components hace
de manera estándar las cosas que todos estos frameworks realizan por cuenta propia, con
implementaciones propietarias, creadas por ellos mismos.

Después del empuje inicial de Google a esta tecnología y con los acercamientos y sugerencias del resto de
fabricantes de navegadores, se ha llegado a una nueva versión del estándar que cubre las necesidades y
expectativas de todos. Hoy podemos decir que Web Components V1 ha sido aceptado por todos los
fabricantes de navegadores, lo que ya mismo es una realidad, no solo en Google Chrome, sino en Safari, y
pronto en Firefox, Edge, etc.

Web Components V1 en el momento de escribir este artículo está totalmente implementado, y de manera
estable, en Chrome y Opera. El navegador Safari dispone de las partes más críticas de Web Components ya
implementadas y Firefox junto con Edge van un poco más retrasados pero han dado el visto bueno también
a la tecnología. De todos modos, independientemente del soporte de los navegadores la tecnología es
perfectamente usable en este momento, pues donde todavía no llega el soporte nativo existen los "Polyfills"
(Librerías de Javascript para implementar soporte a navegadores todavía no compatibles con una tecnología)
que nos permiten ampliar la compatibilidad a todos navegadores del mercado. En la siguiente imagen

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 5 de 93
Manual de Polymer 2

puedes ver el soporte actual (agosto de 2017) en navegadores.

Nota: Esta imagen actualizada la puedes ver en la "Home" de la tecnología Web Components. Allí
encontrarás mucha información del estándar y un catálogo de componentes que puedes usar ya mismo
en cualquier proyecto.

Hoy más que nunca, "UseThePlatform"

"UseThePlatform" se ha usado como el slogan de Polymer y los Web Components. Nos trata de indicar que
usemos en la medida de lo posible lo que el navegador nos ofrece. Todo aquello que el navegador ya
dispone en sus APIs de Javascript es más ligero de ejecutar que cualquier librería que pongamos por encima
para hacer las mismas cosas.

Tenemos que pensar que la web fue ideada para el trabajo con documentos, donde el texto y las imágenes
eran los protagonistas. Sin embargo, con el tiempo la web fue adaptándose a las necesidades de los usuarios
y empresas, volviéndose una plataforma de ejecución de aplicaciones. Frente a esa necesidad nacieron los
frameworks y librerías, que nos ofrecían una base de código útil para realizar todas aquellas cosas que los
estándares no aportaban en el pasado.

En los últimos años desarrollo basado en componentes se ha consolidado como la mejor de las alternativas
y prueba de ello es la adopción del paradigma por todas las librerías y frameworks más usados. Éstos
crearon sus propios mecanismos para que los desarrolladores fueran capaces de construir elementos
encapsulados, con los que resolver las necesidades más diversas. Las aplicaciones más complejas se pueden
implementar en base a componentes, donde unos elementos que se apoyan en otros. El problema es que
toda la base de código que nos aporta un framework tiene un coste elevado, pues ralentiza no solo el tiempo
de carga de las aplicaciones web, sino que además implica mucho esfuerzo en tiempo de procesamiento, ya
que deben procesar mucha cantidad de código al interpretar aplicaciones complejas.

Web Components ha conseguido crear unos estándares abiertos para la construcción de los elementos
personalizados, con código nativo que el navegador puede ejecutar sin esfuerzo. Usar los estándares abiertos

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 6 de 93
Manual de Polymer 2

disponibles para la web, aparte de ofrecer un mejor rendimiento, nos asegura un ciclo de vida de las
aplicaciones más dilatado en el tiempo. Cualquier navegador o cliente web en general, presente o futuro, que
soporte los estándares será capaz de ejecutar las aplicaciones creadas en base Web Components.
Paralelamente, cada vez que los fabricantes de navegadores sean capaces de mejorar la plataforma, las
aplicaciones creadas en base a estándares se verán más directamente beneficiadas.

Polymer es una librería basada en Web Components, por lo que consigue exprimir todos los
comportamientos nativos que nos ofrecen los navegadores para hacer las cosas, de manera más ligera que
otras librerías o frameworks.

Por qué el soporte nativo es crítico, frente a los polyfill

Como hemos dicho, donde no llegan los navegadores existe la posibilidad de cargar Polyfills que ofrecen un
soporte no nativo, tanto a Web Components como a muchas otras tecnologías HTML5. Gracias a los
polyfill conseguimos algo muy importante: cualquier web que use Web Components será compatible en
todos los browsers.

Los Polyfills son por tanto un actor importante en la actualidad, ya que el soporte nativo está siendo
desarrollado por algunos fabricantes todavía. Pero lo cierto es que no son la mejor solución, ya que recargan
el navegador con código Javascript y por tanto lo hacen más lento al procesar páginas basadas en Web
Components.

Al contar con soporte nativo, los navegadores son más rápidos y lo que es tan importante, las webs son más
ligeras de carga, ya que la mayoría del Javascript no se tiene que descargar.

Hoy, las especificaciones más críticas de Web Components están completamente implementadas en
Chrome, Safari y Opera, por lo que no solo ordenadores de escritorio, sino la mayoría de los móviles, son
compatibles de manera nativa con Web Components, lo que resulta un excelente motivo para confiar en
esta tecnología.

Nota: Al tener soporte nativo Web Components lo hace tan rápido como el mismo Javascript "Vanilla",
ya que Web Components es simplemente Javascript.

Sin embargo, para un navegador que dependa de Polyfills, usar Web Components no representaría una
ventaja particular. Dicho de otra forma, una aplicación Angular, React, VueJS, etc., sería similar, a usar Web
Components con Polyfills, pues todos dependerían de Javascript no nativo para implementar cosas
parecidas. Por este motivo, todos los mejores frameworks han anunciado que en un futuro cambiarán su
manera de trabajar, para basarse en el estándar Web Components y apoyarse directamente en el Javascript
nativo, algo que hoy ya tenemos con Polymer 2.

Novedades en Polymer 2.0

Polymer 2.0 es capaz de ir un sensiblemente más lejos de su predecesor, aunque la mayoría de las novedades
más significativas se derivan directamente de las propias novedades del estándar de los Web Components y
su creciente soporte nativo en los navegadores.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 7 de 93
Manual de Polymer 2

Su peso en bytes es aproximadamente un cuarto del peso de Polymer 1.0


Los polyfills están separados por especificaciones del estándar de Web Components, de modo que
se puede limitar mejor la carga de Polyfills a aquellos que realmente el navegador necesita,
reduciendo el peso en bytes de las aplicaciones y el tiempo de arranque a lo mínimo necesario en
cada navegador.
Los Custom Elements ahora se definen mediante clases ES6, algo nuevo en el propio estándar, lo
que reduce la cantidad de código y simplifica la creación de componentes. En el caso de crear un
elemento de Polymer 2.0 la única diferencia está en que no extenderemos de HTMLElement sino
de Polymer.Element.
La interoperabilidad entre componentes, la capacidad de trabajar los unos con los otros, ahora está
directamente ofrecida con el estándar de Web Components.
El uso de Custom Properties de CSS se implementa de manera nativa y compatible con todos los
navegadores modernos, lo que no requiere código extra de la librería.
Existe una capa de compatibilidad que permite el desarrollo híbrido, de componentes con sintaxis
1.x y con sintaxis 2.x, de modo que la migración de aplicaciones existentes sea más sencilla y se
pueda realizar de manera progresiva.

Hay una charla del Google IO 2017 muy interesante sobre las novedades de Polymer 2.0 y los Web
Components en general, en la que ofrecen un dato que me parece importante mencionar sobre los avances
de Polymer 2.0, con respecto al peso en Bytes y la separación del código de los polyfill: "Future, Faster:
Unlock the Power of Web Components with Polymer".

En ella podremos encontrar esta diapositiva, en la que vemos el peso de Polymer junto con los Polyfill en
cada familia de navegadores en la actualidad.

Como se puede ver, en Chrome, que ofrece soporte completamente nativo, el peso de Polymer 2.0 más los
polyfill es de 11KB, en Safari actualmente subiríamos a 14KB, Firefox y Edge 33KB y los antiguos Internet
Explorer 37KB.

Ante esta reducida cantidad de código queda todavía más clara la idoneidad de usar Polymer 2.0 junto con
otros frameworks como podrían ser Angular o React, además de ser posible la interoperabilidad por defecto
de manera nativa por medio del estándar Web Components.

Nota: Hay un matiz que es justo mencionar y es que Polymer 2 no es solo el propio núcleo, sino que
también hay muchas otras cosas que se ofrecen por medio de una biblioteca de componentes ya listos
para usar en las aplicaciones. Cuando decimos que Polymer 2.0 pesa 11KB no se están incluyendo
muchos elementos que sin duda acabarás usando en las aplicaciones, como el sistema de routing, el
sistema de almacenamiento local, los elementos para construir layouts avanzados, elementos de interfaz

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 8 de 93
Manual de Polymer 2

gráfica con aspecto material design, etc.

Conclusión

Éstas y muchas otras novedades permiten ilusionarse con la nueva versión de la librería Polymer para
desarrollo basado en el estándar abierto de los Web Components. Iremos abordando en el futuro, con
nuevos artículos muchas de las novedades interesantes, no solo de la propia librería, sino también del
universo de los custom elements que tenemos a nuestra disposición hoy para el desarrollo basado en
Polymer.

Estamos seguros que estarás ansioso con ver algo de código, así que en la siguiente entrega nos pondremos
manos a la obra con algo más práctico, que nos permita ver cómo construir fácilmente componentes en
Polymer 2.

Puedes ver el siguiente vídeo, con un resumen de las ventajas de Polymer y Web Components V1, además
de un adelanto del próximo artículo de este manual.

Para ver este vídeo es necesario visitar el artículo original en:


http://desarrolloweb.com/articulos/polymer-2-introduccion.html

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 15/08/2017
Disponible online en http://desarrolloweb.com/articulos/polymer-2-introduccion.html

Desarrollo de Web Components V1 frente a Polymer 2


Revisión de la sintaxis y procedimientos para crear un elemento personalizado (custom element)
con Web Components V1, frente al desarrollo con Polymer 2.

En el pasado artículo hemos ofrecido una introducción teórica a los objetivos de Web Components y
Polymer 2, pero no estará completa sin algo de código para que podamos experimentar lo sencillo que
puede llegar a ser crear nuestro primer componente.

El objetivo en esta ocasión es ofrecer un ejemplo de elemento personalizado creado con Web Components
y enfrentar este código al que necesitaríamos para hacer ese mismo componente en Polymer 2, apreciando
las similitudes y también las diferencias. Por tanto, este artículo nos servirá como introducción práctica de
tanto Web Components V1 como de Polymer 2.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 9 de 93
Manual de Polymer 2

Qué es un Custom Element

Pero antes de comenzar cabe aclarar qué significa "Custom Element", la principal de las especificaciones de
Web Components. Básicamente un elemento personalizado es un nuevo elemento de HTML creado por
nosotros mismos para resolver cualquier tipo de necesidad que no esté implementada en el HTML estándar.

Así pues, cuando mencionamos "componente" en general, casi siempre estamos refiriéndonos a un "custom
element". Los componentes pueden ser sencillos o complejos. Los complejos a menudo se apoyan en
componentes más sencillos para resolver las tareas. Una aplicación generalmente será un componente que
contiene a su vez un árbol de componentes que se relacionan entre sí y trabajan para resolver un conjunto
de necesidades de un negocio.

Debes saber que, el marco de la tecnología "Web Components", custom element es solo una de sus
especificaciones y, por lo general, para implementar componentes nos tenemos que apoyar en otras de las
especificaciones, como "Shadow Dom" o "Templates". Puedes saber más sobre generalidades de las
especificaciones en el artículo Qué son Web Components. https://desarrolloweb.com/articulos/que-son-
web-components.html

Cómo se construye un custom element en Web Components V1

Para definir un elemento personalizado se debe utilizar una clase, de programación orientada a objetos. Nos
referimos lógicamente a clases Javascript ES6 como las que explicamos en el manual de la versión 2015 del
estándar ECMAScript (ES6). Posteriormente tenemos que asociar tal clase como un nuevo elemento dentro
del navegador. Ambos pasos los veremos representados en el siguiente código.

// defino la clase con la que implemento el componente

class HolaComponentes extends HTMLElement {

constructor() {

super();

this.attachShadow( {mode: 'open'} ).innerHTML = '<p>Hola! soy un Custom Element!</p>';

// asocio la clase a un nombre de componente

customElements.define('hola-componentes', HolaComponentes);

En el primer pedazo de este código se define una clase llamada HolaComponentes. Como manda el
estándar V1, esta clase debe heredar de un elemento HTML. En este caso usamos "HTMLElement", que es

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 10 de 93
Manual de Polymer 2

la clase que define un elemento HTML predeterminado. La herencia, como debes saber, se indica mediante
la declaración extends, de la que tienes más información en el artículo de Herencia en las clases de Javascript
ES6.

Como código de la clase tenemos básicamente un constructor, que crea un poco de HTML para usarlo
como contenido de nuestro componente. Ese código del constructor usa métodos que pertenecen al API de
Web Components V1. Por tanto, se trata de Javascript estándar, como attachShadow(), método que sirve
para añadir "Shadow Dom" al componente, que básicamente crea un nuevo nodo hijo, dentro del elemento
personalizado, del que pueden a su vez colgar un árbol de etiquetas. El "shadow DOM" tiene la
característica de encapsular el árbol de etiquetas dependientes de un elemento y {mode: 'open'} hace
referencia al nivel de encapsulación. A ese nuevo nodo Shadow DOM le estamos agregando simplemente
un párrafo, gracias a manipular directamente su propiedad innerHTML.

Nota: Si a pesar de estas explicaciones este código te parece muy extraño quizás te ayudaría saber algo
más sobre las clases ES6 y sobre la especificación de Shadow DOM.

En la última línea de código, se define propiamente el nuevo elemento personalizado. La declaración de la


clase ES6 anterior era simplemente una clase, creada en la memoria de Javascript, pero gracias a
customElements.define() podemos usarla como implementación de un nuevo componente. Para ello
debemos indicar el nombre del nuevo elemento personalizado que se está creando: "hola-componentes" y el
nombre de la clase con la que se implementa el componente "HolaComponentes".

Una vez definido el nuevo elemento ya lo puedes usar. Para ello simplemente tienes que colocar en el
cuerpo de la página la etiqueta HTML que se ha definido en la creación del componente.

<hola-componentes></hola-componentes>

Nota: todos los custom elements necesitan en su nombre un caracter "-" al menos, para distinguirlos de
etiquetas estándar HTML existentes o futuras, que no llevan nunca un guión.

Para que quede perfectamente claro, dejamos el listado de este ejercicio en una página HTML completa.

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Test de Custom Element</title>

</head>

<body>

<hola-componentes></hola-componentes>

<script>

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 11 de 93
Manual de Polymer 2

class HolaComponentes extends HTMLElement {

constructor() {

super();

this.attachShadow( {mode: 'open'} ).innerHTML = '<p>Hola! soy un Custom Element!</p>';

customElements.define('hola-componentes', HolaComponentes);

</script>

</body>

</html>

Fíjate que el código anterior es HTML estándar y Javascript nativo, que soportan los navegadores
compatibles con Web Components V1. Para el resto de los navegadores solo funcionaría si se carga el
correspondiente polyfill, cosa que no hemos hecho todavía. En el momento de escribir este artículo, si lo
abres en Chrome, Opera o Safari funcionará. No necesitas cargar ninguna librería extra gracias a su soporte
nativo!

Cómo crear este componente con Polymer 2

Polymer 2 se apoya al máximo en lo que el propio navegador dispone, por lo que no hay mucha diferencia
entre crear un componente nativo o un componente creado con Polymer 2. Pero además te ofrece algunas
nuevas características, como mayor facilidad para crear Shadow Dom, utilidades para mantener el estado del
componente, para gestionar eventos personalizados y sincronizar los valores de las propiedades entre fuera
y dentro del componente, etc. En adelante iremos aprendiendo todas estas ventajas, ahora nos centraremos
en un código suficientemente simple para comenzar sin demasiada dificultad.

Si queremos usar Polymer 2 lo primero que tendremos que hacer es importar la librería, lo que se consigue
con un HTML Import.

Nota: HTML Import es otra de las especificaciones de Web Components que sirve para importar,
adquirir, incorporar código que está en otros documentos HTML.

Por facilitar la labor vamos a usar el CDN de Polymer 2, aunque más adelante veremos que lo común es
usar gestores de dependencias como Bower para traerse el código de Polymer, o de otros elementos en los
que queramos apoyarnos para hacer una aplicación.

<link rel="import" href="https://polygit.org/components/polymer/polymer-element.html">

Una vez realizado el import el navegador ya conoce Polymer, por lo que a continuación podemos crear
nuestra clase ES6 para implementar el componente. Por último tendremos que hacer el correspondiente
customElements.define() para registrar el elemento en el navegador, igual que antes.

El próximo código observarás que Polymer 2 puede ser muy similar en su modo de trabajo a cómo se creó
el componente anteriormente, usando el estándar Web Components V1, sin apoyarse en ninguna librería.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 12 de 93
Manual de Polymer 2

class HolaComponentes extends Polymer.Element {

static get template() { return document.getElementById('mi-template') }

static get is() { return 'hola-componentes'; }

customElements.define(HolaComponentes.is, HolaComponentes);

Las diferencias que debes percibir son:

Extendemos la clase HolaComponentes de Polymer.Element en lugar de HTMLElement.


Creamos el shadow dom a partir de un template. Para ello definimos una propiedad getter llamada
"template" que se encarga de acceder a la página, buscar una etiqueta TEMPLATE a través de su id
"mi-template".
Creamos una propiedad getter que indica el nombre del custom element que estamos
implementando.

Luego el customElements.define() es prácticamente igual. Solo que nos apoyamos en la propiedad "is" de la
clase, para acceder al nombre del custom element que se está definiendo.

Para que esto funcione, en el cuerpo de la página debería figurar el template al que se está accediendo en
"static get template()", que podría tener una forma como esta:

<template id="mi-template">

<p>Hola! soy un Polymer Element simple!</p>

</template>

Nota: Si quieres saber más de templates te recomendamos la lectura del artículo sobre la etiqueta
template de Web Components.

Para acabar, y a fin de no dejar dudas, colocamos el código completo de una página en la que se usa este
componente creado con Polymer 2.

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<link rel="import" href="https://polygit.org/components/polymer/polymer-element.html">

<title>Test de componente usando Polymer 2</title>

</head>

<body>

<template id="mi-template">

<p>Hola! soy un Polymer Element simple!</p>

</template>

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 13 de 93
Manual de Polymer 2

<script>

class HolaComponentes extends Polymer.Element {

static get template() { return document.getElementById('mi-template') }

static get is() { return 'hola-componentes'; }

customElements.define(HolaComponentes.is, HolaComponentes);>

</script>

<hola-componentes></hola-componentes>

</body>

</html>

Nota: Quizás pueda haber decepcionado un poco la cantidad de código necesaria para crear un
elemento de Polymer, en relación a la cantidad de código usando el estándar Web Componentes V1,
pues es incluso algo mayor. Para un componente tan simple como este no hay mucha ganancia entre
usar Polymer o limitarnos al Javascript nativo. No te preocupes, más adelante, cuando las cosas se
pongan un poco más interesantes, observaremos todas las ventajas de apoyarse en Polymer.

Con esto hemos podido realizar nuestro primer acercamiento con código al estándar de Web Components
V1 y a Polymer 2, para crear un primer custom element mediante dos alternativas de código sencillo:
Javascript nativo Vs Polymer.

Solo cabe aclarar que las cosas no se hacen exactamente en Polymer 2 como hemos visto en este artículo,
pues existen algunos otros detalles que todavía no conoces y que debemos de explicar para producir un
código más ajustado a la práctica habitual. En el siguiente artículo podrás profundizar en nuevos conceptos,
abordando la estructura habitual de desarrollo de componentes en Polymer 2.

Formación en vídeo de Web Components V1 y Polymer 2

En noviembre de 2017 impartimos unas clases dedicadas a Web Components y Polymer 2, dentro del
marco del Curso de Polymer 2 de EscuelaIT. En este vídeo que encontrarás a continuación tenemos la
primera de las clases, en la que explicamos muchas cosas altamente relevantes para seguir ahondando en lo
explicado en el presente artículo.

En esta clase comenzamos con una introducción a los Web Components V1 de modo general, explicando
cómo es el desarrollo de componentes usando solamente Javascript. Luego estudiaremos cómo crear esos
mismos componentes mediante Polymer 2.

Para ver este vídeo es necesario visitar el artículo original en:


http://desarrolloweb.com/articulos/desarrollo-web-components-v1-polymer-2.html

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 21/08/2017
Disponible online en http://desarrolloweb.com/articulos/desarrollo-web-components-v1-polymer-2.html

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 14 de 93
Manual de Polymer 2

Estructura de un componente de Polymer 2


Cómo se define un custom element en Polymer 2, reconociendo todas sus partes, englobadas por
la etiqueta dom-module: la clase de definición del componente, su template y los estilos CSS.

En el artículo anterior del Manual de Polymer 2 explicamos cómo crear un primer componente,
centrándonos en dos alternativas de desarrollo: 1) el estándar Web Components V1 y 2) Polymer 2.
Pudimos ver que existen muchas similitudes, ya que la mayoría de lo que se hace en Polymer 2 está definido
por el propio estándar ofrecido por el Javascript nativo.

Sin embargo, ya advertimos que habíamos alterado algo la manera con la que se acostumbra a trabajar en
Polymer 2, con la intención que las diferencias de sintaxis fueran mínimas, con respecto a la alternativa de
desarrollo de custom elements con Javascript nativo.

En este artículo queremos explicar entonces cuál es el modo habitual de desarrollo de un componente de
Polymer, reconociendo sus principales partes. No dista mucho de lo que hemos visto ya, así que seguro que
te resultará sencillo, e incluso más claro y compacto. Además, a las personas que vengan de Polymer 1.x
seguro que les resultará muy familiar.

Etiqueta dom-module

En un elemento de Polymer trabajamos con una etiqueta llamada dom-module, en la cual se engloban las
distintas partes que componen un componente.

Como puedes imaginar, dom-module es un componente en sí, que nos sirve de base para desarrollar
elementos de Polymer 2. En esta etiqueta debemos comenzar indicando como atributo el nombre del nuevo
elemento que se está implementando.

<dom-module id="nombre-componente">

</dom-module>

Entre dom-module y su cierre colocaremos todo el código del componente. Además, como puedes apreciar,
el nombre del componente que se está creando, indicado en el atributo "id", debe de tener al menos un
carácter guión "-".

Es la práctica habitual que el componente se defina en un archivo independiente, que tendrá el mismo

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 15 de 93
Manual de Polymer 2

nombre del elemento, con extensión ".html".

En ese archivo además colocaremos los import HTML de las dependencias del componente, que al menos
será la propia librería Polymer. Es decir, en el archivo HTML de implementación del componente
tendremos algo como esto:

<link rel="import" href="https://polygit.org/components/polymer/polymer-element.html">

<dom-module id="nombre-componente">

</dom-module>

Template del componente

Dentro de un componente de Polymer podemos colocar un template con el código HTML que
necesitaremos para la representación de ese elemento en la página. Las etiquetas HTML que coloquemos en
el template formarán parte del shadow dom del componente que estamos implementando.

El template se indica con su correspondiente etiqueta, de esta manera:

<template>

<h2>Esto es un test</h2>

</template>

Nota: La etiqueta template ya la soportan todos los navegadores y simplemente es como un HTML que
no aparecerá en el cuerpo de la página, hasta que se carge mediante algún tipo de control con Javascript.
Puedes saber más sobre la etiqueta template.

Nosotros como desarrolladores no necesitamos hacer nada para que ese template aparezca en la página al
ser usado el componente. Es decir, el trabajo de volcar ese template en el shadow dom del componente
corre por cuenta de Polymer.

Recuerda que esta etiqueta template la colocarás dentro de dom-module, así que te quedará algo como esto:

<dom-module id="nombre-componente">

<template>

<h2>Esto es un test</h2>

</template>

</dom-module>

Estilos del componente

El componente que estamos generando tiene la posibilidad de tener sus propias reglas de estilos, que no
afectarán más que al HTML que tengamos dentro del template.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 16 de 93
Manual de Polymer 2

El CSS para los estilos lo colocamos dentro de la etiqueta template, como sigue a continuación:

<template>

<style>

h2 {

background-color: orange;

color: white;

</style>

<h2>Esto es un test</h2>

</template>

Como decimos, gracias a la encapsulación de los componentes, son autónomos del resto de la página. Si en
la página donde se use este componente hay un estilo CSS definido para los H2, no entrará en conflicto con
el estilo de nuestro elemento recién creado. Tampoco los estilos definidos en nuestro componente afectarán
al HTML de la página donde se use, o a otros web components que pudiera haber.

Declaración del componente

Ahora nos queda la parte del Javascript, que también debemos colocar dentro de dom-module para que
todo funcione como debería ser. Esa es la parte que ya vimos en el anterior artículo, así que algo ya te debe
de sonar.

Primero tenemos que crear la clase que implementará el componente:

class NombreComponente extends Polymer.Element {

static get is() {

return 'nombre-componente';

constructor() {

super();

Fíjate que debemos nombrar con un getter el componente, en la propiedad "is". El constructor en realidad
no hace nada, por lo que no importa si lo ponemos o no.

Nota: Al heredar nuestra clase de Polymer.Element ya estaría heredando el constructor. Si no


necesitamos hacer nada en especial en el constructor, cosa poco habitual, no sería necesario
sobreescribirlo y así simplemente tomará el de la clase padre. En cambio, si necesitamos realizar alguna
tarea extra en el constructor, estaríamos obligados a llamar a super() antes de realizar cualquier otra cosa.
Por eso no es mala idea que mantengamos nuestro constructor, aunque no haga nada más, con la
llamada a super() para que no se nos olvide colocarla. la necesidad de comenzar por super() en el
constructor está establecida en el estándar de los Web Components V1, pero está derivada del propio
lenguaje Javascript, por motivos que ya fueron explicados en el artículo sobre la herencia dentro de
clases ES6.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 17 de 93
Manual de Polymer 2

Muy importante, debemos colocar luego el correspondiente define(), para que el navegador use esta clase
recién escrita como implementación del nuevo elemento.

customElements.define(NombreComponente.is, NombreComponente);

Todo el código de un componente Polymer 2

Ahora que ya lo tenemos todo, veamos el código completo que hemos generado.

<link rel="import" href="https://polygit.org/components/polymer/polymer-element.html">

<dom-module id="nombre-componente">

<template>

<style>

h2 {

background-color: orange;

color: white;

</style>

<h2>Esto es un test</h2>

</template>

<script>

class NombreComponente extends Polymer.Element {

static get is() {

return 'nombre-componente';

customElements.define(NombreComponente.is, NombreComponente);

</script>

</dom-module>

Este código lo colocaremos, como se ha dicho, en un archivo aparte, que generalmente llamaremos con el
mismo nombre del componente, en este caso "nombre-componente.html".

Recuerda que, para poder usarlo desde otra página web, debes realizar el correspondiente import en la
página donde deseas que este componente se conozca.

<link rel="import" href="elementos/navegador-secciones.html">

Y luego por supuesto colocar la etiqueta del componente, y su cierre, en el lugar donde quieres que
aparezca.

<nombre-componente></nombre-componente>

Ejemplo de otro componente Polymer

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 18 de 93
Manual de Polymer 2

Ahora vamos a ver el código de otro componente simple. Es prácticamente igual que el anterior, aunque
tiene un DOM un poquito más extenso y unos estilos un poco más elaborados.

<link rel="import" href="https://polygit.org/components/polymer/polymer-element.html">

<dom-module id="navegador-secciones">

<template>

<style>

nav {

background-color: #eef;

padding: 10px;

ul {

margin: 0;

padding: 0;

list-style-type: none;

li {

display: inline-block;

margin-left: 15px;

</style>

<nav>

<ul>

<li>

<a href="pagina1.html">

Enlace 1

</a>

</li>

<li>

<a href="pagina2.html">

Enlace 2

</a>

</li>

<li>

<a href="pagina3.html">

Enlace 3

</a>

</li>

</ul>

</nav>

</template>

<script>

class NavegadorSecciones extends Polymer.Element {

static get is() { return 'navegador-secciones'; }

customElements.define(NavegadorSecciones.is, NavegadorSecciones);

</script>

</dom-module>

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 19 de 93
Manual de Polymer 2

Te puede llamar la atención que no estamos usando ninguna clase (class de CSS) en el template ni en los
estilos, algo que sería muy necesario en el HTML/CSS tradicional para poder definir el aspecto de
elementos específicos, sin que afecten al resto. Esto es gracias a la encapsulación, ya que los estilos no salen
para fuera del componente.

Por si no quedase claro, dejamos el listado de un archivo donde hacemos uso de los dos componentes
creados en este artículo:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>Document</title>

<style>

h2 { font-size: 4em; color: red;}

</style>

<link rel="import" href="elementos/nombre-componente.html">

<link rel="import" href="elementos/navegador-secciones.html">

</head>

<body>

<h2>Los estilos del H2 afectan solo a esta etiqueta</h2>

<nombre-componente></nombre-componente>

<navegador-secciones></navegador-secciones>

</body>

</html>

Vídeotutorial estructura de un componente

Ahora puedes complementar las explicaciones de este artículo mediante el siguiente videotutorial en el que
repasamos la estructura de un componente desarrollado con Polymer 2.

Para ver este vídeo es necesario visitar el artículo original en:


http://desarrolloweb.com/articulos/estructura-componente-polymer-2.html

En el siguiente artículo abordaremos otro de los puntos importantes para completar nuestros primeros
pasos con la liberería Polymer, explicando algunas de sus principales herramientas, que componen el
toolbox de Polymer 2.

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 28/08/2017
Disponible online en http://desarrolloweb.com/articulos/estructura-componente-polymer-2.html

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 20 de 93
Manual de Polymer 2

Instalar Polymer 2
Cómo instalar Polymer 2. Comenzamos a explicar flujos de trabajo habituales con Polymer 2 y las
herramientas disponibles en el Polymer CLI. Estructura de una aplicación básica.

En los pasados artículos del Manual de Polymer 2 hemos comenzado a usar la librería para el desarrollo de
componentes muy sencillos, lo que seguramente nos han dado una idea sobre lo fácil que es extender la web
con nuevos elementos que resuelvan necesidades de las aplicaciones. Sin embargo, nos hemos saltado toda
la parte dedicada al flujo de trabajo habitual al trabajar con Polymer, que será necesario conocer para sacarle
partido a las herramientas (toolbox) que se han creado para mejorar la productividad y las aplicaciones
desarrolladas.

Así pues, vamos a ponernos manos a la obra para dedicar un poco de tiempo a conocer algunas
herramientas y utilidades, así como pasos necesarios para instalar Polymer 2 en local y comenzar a
desarrollar más profesionalmente.

Sistema de control de versiones Git

El primer paso para poner nuestros ordenadores a punto es instalar Git. Git, por si no lo sabes, es un
sistema de control de versiones muy popular, usado en la industria en la mayoría de las empresas. Ya hemos
tenido ocasión de explicar esta herramienta en el Manual de Git, por lo que no vamos a abordar todo desde
cero, sino centrarnos en por qué es importante Git en Polymer.

Polymer no te obliga a trabajar con un sistema de control de versiones, o con Git en particular, pero sí es
necesario para trabajar con Bower, del que hablaremos de aquí a poco. No obstante, algunas de las
herramientas de Polymer 2 sí usan Git, por ejemplo los templates para comenzar aplicaciones sobre una
base de código.

Por tanto, debes comenzar por hacerte con Git, en la página https://git-scm.com/ Encontrarás versiones
para tu sistema operativo, ya sea Windows, Linux o Mac Os X.

Gestor de dependencias Bower

Bower es el sistema más utilizado en Polymer para el mantenimiento de las dependencias. Básicamente
Bower sirve para mantener dependencias en proyectos frontend en general, y aunque actualmente no es el
más completo ni el más recomendable, sí es el más simple.

Por si no lo sabes, un gestor de dependencias es un software que sirve para instalar y mantener actualizadas

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 21 de 93
Manual de Polymer 2

todas las piezas de software que usas para desarrollar un proyecto. Cuando creas una aplicación
generalmente no lo haces desde cero y te apoyas en una serie de librerías, plugins, componentes, etc.
generalmente de código abierto. Todo eso son las dependencias y Bower te sirve para mantenerlas al día.

Como vamos a necesitar Bower, te recomendamos instalarlo y conocer sus comandos básicos. Como este
tema ya lo hemos tratado previamente, te recomendamos el artículo de Bower para obtener más
información.

Polymer CLI

Ahora sí, vamos a conocer las herramientas específicas de Polymer 2 y debemos comenzar por el Polymer
CLI. CLI son las siglas de Cliente por línea de comandos y básicamente es una herramienta heredada de
Polymer 1, ya revisada en el pasado en el artículo sobre Polymer CLI,
https://desarrolloweb.com/articulos/polymer-cli.html que funciona de manera similar en la versión 2.

Para instalar el CLI de Polymer tienes que disponer de NodeJS instalado en tu máquina. Por lo que deberías
entrar en la página de Node https://nodejs.org/es/ y descargar el instalador.

Nota: NodeJS también es necesario para poder instalar Bower, así que asumimos que ya sabes algo de
esta plataforma. Instalarla es tan fácil como usar el instalador o si estás en Linux hacerlo con sus
repositorios. No obstante, tenemos el Manual de Node para más información.

El comando que debes lanzar para instalar el Polymer CLI es:

npm install -g polymer-cli

A partir de entonces dispondrás de una serie de comandos nuevos relacionados con Polymer, para crear
aplicaciones, para servir páginas y aplicaciones, llevarlas a producción, para crear proyectos de
componentes, etc. Todos los comandos del CLI comienzan con la palabra "polymer" seguida de la acción
que quieras realizar.

Crear un proyecto vacío

Una de las primeras acciones que debes aprender es a inicializar proyectos. Existen diversos tipos de
proyectos que puedes crear con el CLI de Polymer, aunque de momento vamos a crear uno vacío.

El comando para comenzar es "polymer init", aunque te recomendamos hacerlo desde una carpeta vacía.
Debes abrir una ventana del terminal y luego crear la carpeta en el directorio donde coloques tus proyectos.

mkdir test-cli

Luego te mueves a esa carpeta:

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 22 de 93
Manual de Polymer 2

cd test-cli

Ahora puedes crear tu proyecto Polymer con:

polymer init

Verás que te ofrece una serie de alternativas, de momento podemos crear una aplicación vacía con la opción
"polymer-2-application". Puedes seleccionarla con los cursores y luego apretar "enter".

Te pide entonces varias informaciones, como:

El nombre de la aplicación
El elemento principal, raíz de todos los componentes que formarán parte de tu aplicación
Una breve descripción de la aplicación

Nota: Estas solicitudes de información de momento no son demasiado importantes, pues estamos en
un simple test. Podemos poner cualquier cosa. Además ofrece unos valores por defecto que colocará si
no introducimos otros. El componente raíz, por si no lo sabes, es el elemento que mantendrá el código
de toda tu aplicación, que usualmente se apoyará en un árbol de componentes para realizar todas las
tareas que sean necesarias.

Con esto Polymer CLI se encarga de crearnos una estructura de proyecto simple y descargar la lista de
dependencias inicial. Las carpetas y archivos serán parecidos a estos:

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 23 de 93
Manual de Polymer 2

Nota: no te asustes con la cantidad de carpetas que crea, o las dependencias situadas en la carpeta
"bower_components". Realmente de momento no necesitamos tantas cosas, pero lo cierto es que hay
mucho trabajo ya listo para facilitarnos la vida, al que le sacarás provecho en su debido momento.

Servir un proyecto

Polymer saca gran partido de las últimas características de la plataforma web, y muchas de ellas requieren
niveles de seguridad determinados, que solo están disponibles cuando se accede a las páginas por medio de
un servidor.

Es por ello que, en muchos casos, para ejecutar un proyecto realizado con Polymer no podemos
simplemente dar un doble clic a un archivo ".html" para abrirlo en el navegador. En cambio, debemos
abrirlo a través de un servidor web.

Debido a la necesidad de un servidor web, el propio CLI incorpora uno, que podemos lanzar con el
comando:

polymer serve

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 24 de 93
Manual de Polymer 2

Esto arranca un servidor web y nos muestra la dirección a la que tenemos que acceder en el navegador para
abrir nuestro proyecto. Esta es la salida (o una parecida) que veremos al ejecutar el comando desde la
carpeta de nuestra aplicación vacía de Polymer:

Ahora ya solo queda acceder a esa URL en el navegador para ver la aplicación funcionando.

Utiliza CTRL + C para salir del servidor y dejar de servir la aplicación.

Compilación de ES6 a ES5 y build

El CLI de Polymer también hace tareas importantes para cuando llevamos a producción un proyecto, entre
otras la compilación y compactación del código de componentes y aplicaciones. Dado que Web
Components V1 usa la versión de Javascript ES6, es importante que se ofrezca una versión transpilada a
ES5 para los navegadores que no soportan ES6.

En el proceso de "build" (comando "polymer build" del CLI) se hacen estas tareas. También, el comando
"polymer serve" se encarga la traducción a ES5 en tiempo de ejecución, si el navegador cliente lo require.
De momento no vamos a entrar en más detalles porque hay temas más urgentes de conocer antes de llevar a
producción aplicaciones desarrolladas con Polymer 2.

Estructura del proyecto

Ahora voy a describir brevemente la estructura del proyecto, no ítem por ítem, sino simplemente lo que
necesitamos reconocer para empezar a trabajar.

Carpeta "bower_components": aquí se guardan las dependencias instaladas por Bower. Verás el
código de Polymer, el código de los Polyfills que algunos navegadores necesitan y algunos
componentes básicos que se pre-instalan con tu aplicación.
Carpeta "src": Aquí están las fuentes de código de los componentes de tu aplicación. De
momento solo hay un componente, que es el componente raíz.
index.html: este es el archivo inicial, que arrancará tu aplicación. En el código del index encuentras
cosas muy importantes, básicas para que tu aplicación se arranque y funcione correctamente.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 25 de 93
Manual de Polymer 2

Nota: Luego veremos otros tipos de proyectos que también creamos mediante el Polymer CLI y que
disponen de estructuras de más complejas, con mucho más código creado de antemano y capaces de
satisfacer otras necesidades y casos de uso.

Código destacable del index.html

En este momento queremos que te fijes en unos pedazos de código importantes como estos:

1.- La inclusión del script "webcomponents-loader.js", que es el archivo que se encarga de cargar todos los
polyfills necesarios, para que el navegador donde se esté ejecutando la aplicación sea compatible con Web
Components V1.

<script src="/bower_components/webcomponentsjs/webcomponents-loader.js"></script>

2.- El import del componente raíz de la aplicación, que está en la mencionada ruta "src".

<link rel="import" href="/src/test-cli-app/test-cli-app.html">

Nota: repara que el componente raíz en tu caso puede tener nombre distinto, pues depende de lo que
indicaste en las preguntas derivadas de la ejecución del comando "polymer init".

3.- El uso del componente raíz, que es el único contenido que se encuentra en el BODY de la página.

<test-cli-app></test-cli-app>

Ese componente es el padre de todo el árbol de componentes que componen una aplicación compleja en
Polymer.

Flujo de trabajo para desarrollar con Polymer 2

Como hemos prometido, queremos avanzar un poco más para ver cómo sería el modo de desarrollo de una
aplicación Polymer con las herramientas que ya conocemos. Para ello vamos a modificar un poco el
componente raíz, colocando alguna cosa adicional. Mi objetivo ahora es mostrar cómo somos capaces de
instalar nuevos componentes entre las dependencias del proyecto y cómo se usarían.

Vamos a usar un nuevo componente para crear campos "input" con el aspecto de "Material Design". Ese
componente ya está creado y forma parte de la biblioteca de elementos de Polymer. Puedes conocerlo en la
página https://www.webcomponents.org/element/PolymerElements/paper-input

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 26 de 93
Manual de Polymer 2

Lo instalamos mediante el gestor de dependencias Bower, usando el comando que está en la propia página
del componente, que puedes ver pulsando el icono "+" de la izquierda.

bower install --save PolymerElements/paper-input

Lanzamos ese comando desde el terminal, situados en la carpeta del proyecto. Con ello se instalará el
componente en la carpeta "bower_components/paper-input".

Ahora vamos a usar ese componente. Para ello vamos al elemento raíz de la aplicación y lo abrirmos para su
edición. En mi caso el elemento raíz está en "test-cli/src/test-cli-app/test-cli-app.html".

Si abres ese componente raíz deberías de reconocer algo su código, pues es muy parecido al que hemos
visto en artículos anteriores de este manual de Polymer 2.

El primer paso para usar un componente recién instalado es realizar el correspondiente import, para que el
elemento se conozca en el contexto de la aplicación. Ese import lo puedes colocar al principio del
componente, después del import de la librería Polymer.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 27 de 93
Manual de Polymer 2

<link rel="import" href="../../bower_components/paper-input/paper-input.html">

Ahora ya podemos usarlo, para lo cual vamos a colocarlo en el template (Dentro de la etiqueta TEMPLATE
del componente raíz).

<paper-input label="Escribe algo" value="{{prop1}}"></paper-input>

El template del componente te podría quedar algo como esto:

<template>

<style>

:host {

display: block;

</style>

<h2>Hello [[prop1]]!</h2>

<paper-input label="Escribe algo" value="{{prop1}}"></paper-input>

</template>

Ahora puedes refrescar la página para ver los cambios, siempre que tengas el servidor encendido. Si lo
paraste previamente tendrás que hacer de nuevo el "polymer serve".

Te debería aparecer algo como esto:

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 28 de 93
Manual de Polymer 2

Para acabar fíjate que ocurre cuando cambias el texto del componente paper-input, que tiene escrito
inicialmente "test-cli-app" (en mi caso, en tu caso debe aparecer el nombre del componente raíz). Si te
cambia el titular H2 de la página es que está funcionando tal como se esperaba. Ese es un ejemplo de
binding, algo que te permite hacer Polymer de una manera muy simple y de lo que ya hemos introducido
algunas pequeñas informaciones, aunque todavía nos toca verlo en detalle.

Espero que lo que has visto hasta ahora te vaya gustando. Aunque lo cierto es que hay mucho todavía que
contar para dominar todo a lo que nos hemos asomado en este artículo, ya que solo hemos jugado un poco
con algunas de las herramientas más simples disponibles en el CLI.

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 01/09/2017
Disponible online en http://desarrolloweb.com/articulos/instalar-polymer-cli.html

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 29 de 93
Manual de Polymer 2

Generalidades para el desarrollo de


componentes

En los siguientes artículos vamos a abordar los conocimientos fundamental para trabajar con Polymer 2.
Veremos cuáles son las utilidades más importantes que nos ofrece la librería para desarrollar, como las
propiedades, el binding de datos y los eventos. Este conocimiento de base luego lo utilizaremos durante
todo el manual, y se aplicará en cualquier componente por sencillo que sea.

También veremos cómo es el ciclo de vida de los componentes, algo que todo desarrollador debe conocer
para poder sacar partido al desarrollo con Web Components, apreciando cómo en muchos de los casos el
propio Javascript estándar es la base de todo lo que nos encontramos dentro de Polymer 2.

Introducción al desarrollo de componentes con Polymer 2


Esta es una clase práctica sobre desarrollo de componentes de Polymer 2, con vídeo incluido.
Veremos binding, propiedades, eventos, ajax para acceso a API REST y colaboración entre
componentes.

Para comenzar en tu aprendizaje de la librería Polymer 2, te ofrecemos ahora una vista de pájaro sobre el
desarrollo de componentes. En este artículo encontrarás ejemplos prácticos de las posibilidades de Polymer
2, en cuanto a la creación de componentes personalizados, que sin duda te ofrecerán una visión general de
muchas de las cosas que puedes hacer con esta librería y muy poco esfuerzo.

Abordaremos diversos conceptos de una manera muy resumida, sin entrar en detalles. Más adelante, a lo
largo de muchos otros artículos de este manual, encontrarás descripciones y explicaciones más detalladas
sobre todos estos conceptos, y muchos otros.

Este artículo surge como un resumen de la clase 02 del Curso de Polymer 2 en EscuelaIT, que hemos
impartido de manera gratuita para todos los interesados en aprender las mejores técnicas de desarrollo
frontend, basado en el estándar de Web Components.

Qué aborda esta clase de Polymer 2

En resumen, los puntos que vamos a tratar en esta clase son los siguientes:

Qué ofrece Polymer 2: Veremos qué es lo que Polymer 2 te ofrece, encima del estándar de los Web
Components y qué tipo de proyectos puedes realizar con Polymer 2.

Flujo de desarrollo de componentes: Veremos la herramienta que se usa en Polymer para el desarrollo de
componentes y aplicaciones, el Polymer CLI junto con Bower (aunque dentro de poco se usará Yarn para
sustituir a Bower), con una breve descripción sobre cómo instalar componentes en un proyecto y cómo
importar las dependencias.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 30 de 93
Manual de Polymer 2

Ejemplos prácticos: En los ejemplos prácticos desarrollados en esta clase encontraremos explicaciones
básicas sobre las tres herramientas más básicas disponibles para el desarrollo de componentes: Propiedades,
Binding y Eventos.

Qué ofrece Polymer encima de Web Components V1

Polymer ofrece muchas herramientas para desarrolladores de componentes. Ofrece una manera de
desarrollar custom elements mucho más ágil y amistosa para el desarrollador, frente a usar sólo Javascript
nativo. En este listado encontrarás básicamente lo que el "core" de Polymer 2 te entrega, encima de Web
Components V1.

Nota: recordando que Polymer 2, el core o núcleo, pesa apenas 12 KB y que existen muchas otras
herramientas ofrecidas por la librería en diversos componentes que se pueden cargar, opcionalmente si
se necesitan, y que ampliarían este listado enormemente. Así pues, nos estamos centrando sólo en lo que
te ofrece el Polymer.Element, la clase que usamos para extenderla y crear nuestros propios componentes
Polymer 2.

Renderización del template en el Shadow Dom


Propagación del estado
Binding de 1 dirección [[ ]]
Binding de 2 direcciones {{ }}
Definición declarativa de manejadores de eventos personalizados
Sincronización de los atributos (en la etiqueta del componente) a propiedades (dentro del propio
componente)

Los próximos componentes que vamos a usar como ejemplo usan básicamente estas características, así que
nos quedarán mucho más claras en pocos minutos, viendo el vídeo de la clase que encuentras a final de este
texto.

Qué incluye Polymer 2 y qué tipo de proyectos puedes realizar

Además de una serie de herramientas para construir fácilmente Custom Elements, Polymer dispone de un
completo catálogo de componentes listos para usar en cualquier tipo de aplicación.

Paralelamente, una amplia comunidad de desarrolladores está publicando constantemente nuevos


componentes que también podrás usar en tus sitios y aplicaciones.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 31 de 93
Manual de Polymer 2

En la Home de Web Components podrás encontrar una clasificación enorme de custom elements listos
para usar en cualquier proyecto, hechos con Polymer, Javascript nativo, o cualquier librería existente.
Además en la misma web encontrarás el catálogo de componentes realizados por el equipo de Polymer.

Con todas estas herramientas te dejan muy sencillo usar Polymer en todo tipo de proyectos,
independientemente de cuál es el stack de tecnologías que se esté usando. Podríamos dividir los casos de
uso en dos clasificaciones:

Componentes para usar en sitios web: Con Polymer 2 puedes usar componentes y esos componentes
serás capaz de implementarlos en cualquier sitio web. Es lo mismo que tu sitio use PHP, WordPress,
Laravel, Python, Django, Node, Java... o lo que sea. Polymer se usa para el desarrollo frontend y es lo
mismo lo que tengas del lado del servidor. Así mismo, los componentes de Polymer se pueden usar junto
con componentes de otros frameworks como Angular, o React. De hecho, Polymer no busca sustituir a una
de estas librerías (aunque en la práctica sí podrías), sino servir de complemento estándar para todo tipo de
componente que podrías usar en cualquier tipo de sitio web.

Desarrollo de aplicaciones frontend completas: Con Polymer podemos hacer completas aplicaciones
web de última generación, o Progressive Web Apps. En general con Polymer y usando diversos
componentes del catálogo, te ponen muy fácil desarrollar aplicaciones SPA (Single Page Application) o
aplicaciones progresivas, simplemente juntando bloques.

Flujo de desarrollo con Polymer

En esta clase te enseñaremos también cuál es el flujo de desarrollo de aplicaciones con Polymer 2.
Explicaremos asuntos como el Polymer CLI (las herramientas de línea de comandos disponibles en Polymer
para crear nuevos proyectos y componentes) y Bower. Verás también cómo gestionar dependencias en
proyectos, partiendo desde cero.

Como esto es material de otros artículos, te recomendamos ver la clase o explorar el Manual de Polymer 2
para encontrar más información detallada.

Ejemplos prácticos de componentes con Polymer 2

A partir de aproximadamente el minuto 15 y hasta el final de la clase veremos ejemplos de componentes de


Polymer 2, creados en directo, en los que iremos abarcando muchas de las posibilidades de esta librería de
Google.

Básicamente lo que vamos a construir es un par de componentes que colaboran entre sí para realizar algo en
común. Nuestro objetivo final es mostrar un listado de instrumentos musicales y para ello tendremos dos
componentes.

Componente listado de instrumentos: Realizará una llamada a un API REST para obtener un
listado de instrumentos musicales que mostrar, por medio de una solicitud GET con Ajax. El
listado que el API REST entrega es en sí un array, que por medio de un template de repetición, se
mostrará en la página. Para mostrar cada uno de los instrumentos del listado nos apoyaremos en
otro componente creado por nosotros.
Componente instrumento musical: el componente del listado se apoyará en el componente del
instrumento. Cada uno de los instrumentos musicales se presentarán con un componente

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 32 de 93
Manual de Polymer 2

específico, que encapsula la complejidad de realizar una tarjeta de un instrumento. En este


componente además nos apoyaremos en otro componente del catálogo de Polymer que nos
permitirá realizar un sencillo comportamiento dinámico.

Lo que veremos en resumen en la clase nos ayudará a ver asuntos clave en el desarrollo de componentes
Polymer 2 como el binding, la declaración de propiedades, eventos, el uso de componentes adicionales del
catálogo de Polymer, la colaboración entre componentes para dividir las tareas por responsabilidades, etc.

Código de los componentes vistos en clase

Ahora dejamos el código de los componentes desarrollados durante la clase, para que quede como
referencia a cualquier persona interesada.

Componente instrumento-musical

Este es el componente que permite mostrar una tarjeta de un instrumento musical, es decir, cada uno de los
item del listado.

<link rel="import" href="../bower_components/polymer/polymer-element.html">

<link rel="import" href="../bower_components/iron-collapse/iron-collapse.html">

<dom-module id="instrumento-musical">

<template>

<style>

:host {

display: block;

padding: 10px 15px;

background-color: rgb(211, 247, 247);

color: rgb(36, 54, 77);

border-radius: 6px;

font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;

margin-bottom: 10px;

h1 {

font-size: 1.4em;

margin: 0;

color: #f52757;

p {

font-size: .9em;

color: #2055a8;

p span {

font-weight: bold;

</style>

<h1 on-click="toggle">[[nombre]]</h1>

<iron-collapse opened="[[desplegado]]">

<p on-click="resaltarDescripcion">[[descripcion]]</p>

<p><span>Clasificación:</span> [[clasificacion]]</p>

</iron-collapse>

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 33 de 93
Manual de Polymer 2

</template>

<script>

class InstrumentoMusical extends Polymer.Element {

static get is() {

return 'instrumento-musical';

static get properties() {

return {

nombre: String,

clasificacion: {

type: String,

value: 'Sin clasificar'

},

descripcion: String,

desplegado: {

type: Boolean,

value: false

};

resaltarDescripcion(e) {

console.log(e);

this.descripcion = this.descripcion.toUpperCase();

toggle() {

this.desplegado = !this.desplegado;

window.customElements.define(InstrumentoMusical.is, InstrumentoMusical);

</script>

</dom-module>

Componente listado-instrumentos

Este es el código del componente que hace el listado de instrumentos musicales, que ha obtenido por medio
de una conexión Ajax a un API REST. Se apoya en el componente anterior para realizar la tarea.

<link rel="import" href="../bower_components/polymer/polymer-element.html">

<link rel="import" href="../bower_components/polymer/lib/elements/dom-repeat.html">

<link rel="import" href="../bower_components/iron-ajax/iron-ajax.html">

<link rel="import" href="./instrumento-musical.html">

<dom-module id="listado-instrumentos">

<template>

<style>

:host {

display: block;

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 34 de 93
Manual de Polymer 2

</style>

<iron-ajax

id="ajax"

url="http://localhost:3000/instrumentos"

last-response="{{instrumentos}}"

loading="{{cargando}}"

></iron-ajax>

<template is="dom-repeat" items="[[instrumentos]]">

<instrumento-musical

nombre="[[item.nombre]]"

descripcion="[[item.descripcion]]"

clasificacion="[[item.clasificacion]]"

></instrumento-musical>

</template>

<button on-click="obtener">Recuperar datos</button>

</template>

<script>

class ListadoInstrumentos extends Polymer.Element {

static get is() {

return 'listado-instrumentos';

static get properties() {

return {

cargando: Boolean,

instrumentos: {

type: Array,

value: function() {

return [];

};

obtener() {

this.$.ajax.generateRequest();

window.customElements.define(ListadoInstrumentos.is, ListadoInstrumentos);

</script>

</dom-module>

JSON para realizar el API REST

Otra cosa que necesitarás para realizar estos ejemplos es el JSON que usamos para implementar el API
REST. Estamos usando JSON Server, que nos permite crear un sistema REST en local, que es un paquete
que explicamos con detalle en el artículo de JSON Server.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 35 de 93
Manual de Polymer 2

Este es el aspecto de nuestro JSON, que no reproduzco entero pues realmente lo que te interesa es la
estructura de los datos.

"instrumentos": [

"nombre": "Guitarra",

"clasificacion": "cuerda",

"descripcion": "Instrumento musical de cuerda, con una caja de resonancia y seis cuerdas en un mástil..."

},

"nombre": "Tambor",

"clasificacion": "percusión",

"descripcion": "Instrumento de naturaleza variada que permite golpear una membrana que producen el sonido..."

Vídeo de la clase de Polymer 2 impartida en directo

Por último, te dejamos el vídeo de la clase completa de introducción al desarrollo de componentes con
Polymer 2. Esperamos que puedas aprovecharlo y seguir la práctica realizada en clase para enfrentarte al
desafío de crear tus primeros componentes personalizados.

Para ver este vídeo es necesario visitar el artículo original en:


http://desarrolloweb.com/articulos/introduccion-desarrollo-componentes-polymer-2.html

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 28/11/2017
Disponible online en http://desarrolloweb.com/articulos/introduccion-desarrollo-componentes-polymer-2.html

Propiedades y estado de los componentes en Polymer 2


Cómo definir propiedades de los componentes, aplicar data binding en el template y modificar los
valores de los atributos del componente para alterar el estado.

Ahora que ya conocemos la estructura básica de un elemento Polymer 2 podemos centrarnos en aprender a
trabajar con sus propiedades, que nos permitirán manejar el estado de los componentes.

Los elementos realizados hasta este punto en el Manual de Polymer 2, solo tenían algo de HTML y unos
simples estilos. Ahora vamos a darles algo más de sentido gracias a las propiedades, que pueden almacenar
valores que podrán variar a lo largo del tiempo. Además, gracias al data binding, podemos conseguir que el
componente cambie de estado al cambiar las propiedades, sin invertir más líneas de código.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 36 de 93
Manual de Polymer 2

Declaración de las propiedades

Las propiedades deben declararse en la clase de implementación del componente. Para indicarlas usaremos
un getter, de manera parecida a lo que hacíamos al definir la propiedad "is".

Se definen devolviendo un objeto con todas las propiedades que nuestro componente vaya a necesitar.
Podemos especificar muchas cosas al declararlas y gracias a ello podrán tener distintos comportamientos
que nos facilitarán diversas situaciones. Justamente esta riqueza en la declaración de propiedades es una de
las ventajas de usar Polymer, con respecto a lo que nos ofrece el Javascript nativo de Web Components.

class EstadoAnimo extends Polymer.Element {

static get is() {

return 'estado-animo';

static get properties() {

return {

animo: {

type: String,

value: 'feliz'

customElements.define(EstadoAnimo.is, EstadoAnimo);

En este código has visto cómo se define una propiedad de tipo cadena de caracteres y a la cual hemos
inicializado con un valor determinado.

Binding del valor de las propiedades al template

Otra de las ventajas de Polymer es que, mediante una simple sintaxis en el template, podemos volcar el valor
de una propiedad en la representación del componente.

En nuestro template simplemente usamos dos llaves para volcar el contenido de una propiedad del
componente.

<template>

<style>

span {

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 37 de 93
Manual de Polymer 2

text-transform: uppercase;

</style>

<div>

Hoy me encuentro <span>{{animo}}</span>

</div>

</template>

Fíjate que al referirnos a una propiedad simplemente tenemos que indicar su nombre {{animo}} y el
contenido de ella se colocará en el propio HTML del componente. Además, si la propiedad cambia en
cualquier momento, Polymer se encargará de actualizar el template para representar el nuevo estado, sin que
tengamos que intervenir de alguna manera.

Nota: Existen diversos tipos de binding, de una o dos direcciones. De momento nos vamos a olvidar de
esa parte, aunque a decir verdad en este template poco importa, porque al volcar texto en una etiqueta
HTML básica, el dato no tiene como viajar más que en una dirección.

Las propiedades se asocian a atributos del mismo nombre en el elemento HTML

Otra de las cosas básicas que debemos saber de las propiedades es que en los componentes se pueden
colocar atributos y asignarles desde fuera valores.

El ánimo predeterminado, definido al declarar la propiedad "animo" era "feliz", pero cuando estemos
usando este componente podremos asignarle cualquier estado de ánimo que nos venga en gana, o que
necesitemos para nuestra aplicación.

<estado-animo animo="sorprendido"></estado-animo>

Los atributos definidos fuera viajan dentro del componente y modifican su estado. Pero como además todo
esto es en el fondo Javascript nativo, si manipulamos el DOM con Javascript, también se alterará el
componente.

Como sabes, puedes cambiar el valor de un atributo a través del método setAttribute() y con ello veremos
que el nuevo valor viaja hacia dentro en el componente.

En este pequeño código hemos jugado algo con esta posibilidad y hemos creado un par de botones para
manipular desde fuera el estado de las propiedades del componente, asignando nuevos estados de ánimo,
que al cambiar alterará la representación del elemento.

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge">

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 38 de 93
Manual de Polymer 2

<title>Test con ánimos</title>

<link rel="import" href="elementos/estado-animo.html">

</head>

<body>

<estado-animo animo="sorprendido" id="displayanimo"></estado-animo>

<button id="botoncontento">Ponerse contento</button>

<button id="botontriste">Ponerse triste</button>

<script>

function ponerContento(){

document.getElementById('displayanimo').setAttribute('animo', 'contento');

function ponerTriste(){

document.getElementById('displayanimo').setAttribute('animo', 'triste');

document.getElementById('botoncontento').addEventListener('click', ponerContento);

document.getElementById('botontriste').addEventListener('click', ponerTriste);

</script>

</body>

</html>

Videotutorial propiedades declaradas Polymer 2

Si lo deseas, puedes aprender algunas de las cosas que hemos explicado en este artículo en el siguiente
videotutorial. En el vídeo podrás encontrar una breve explicación de las propiedades declaradas, junto con
un ejemplo de declaración de propiedades en un componente. Verás que las propiedades una vez declaradas
las podemos usar en el template y aprenderás a inicializar las propiedades, cargando los valores a través de
atributos en la etiqueta del componente.

Para ver este vídeo es necesario visitar el artículo original en:


http://desarrolloweb.com/articulos/propiedades-estado-componentes-polymer-2.html

Conclusión

Hemos conocido de manera resumida las propiedades de los elementos de Polymer. Trabajar con ellas es
realmente sencillo y nos permiten hacer gran cantidad de cosas realmente útiles.

Como hemos dicho, existen diversos tipos de propiedades, y no solo nos referimos a que tengan un tipo de
datos o de otro, sino que posean comportamientos especiales que nos ayuden a resolver determinadas
situaciones. Por ejemplo existen las propiedades computadas, que usan una función para resolver su valor,
las propiedades capaces de notificar al padre de los cambios, etc. Además existe la posibilidad de observar
valores de las propiedades para implementar programación reactiva. Todo esto lo iremos viendo con calma
más adelante, en próximos artículos, aunque si vienes de Polymer 1 estamos seguros que te podrás ir
haciendo una idea.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 39 de 93
Manual de Polymer 2

En la siguiente entrega del Manual de Polymer 2 podrás encontrar una información muy útil sobre el ciclo
de vida de los componentes (del estándar Web Components V1 y los que agrega Polymer 2).

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 05/09/2017
Disponible online en http://desarrolloweb.com/articulos/propiedades-estado-componentes-polymer-2.html

Ciclo de vida Web Components V1 + Polymer 2


Qué es el ciclo de vida de los componentes y los métodos callback disponibles en el estándar de
Web Components V1 y en la librería Polymer 2.

Para el desarrollo basado en componentes, el estándar de Web Components V1 ha establecido una serie de
métodos que nos permiten realizar tareas a medida que ocurren ciertas cosas con los elementos
personalizados, como su creación, inserción en la página, eliminación de la página, etc. Todos estos estados
por los que pasa un componente se llaman el ciclo de vida y es algo que debemos conocer cuando vamos a
trabajar con Polymer 2.

Para cada estado se puede asociar lo que se llama una "función callback", que contiene el código que
queremos ejecutar como respuesta a ese cambio en el estado del elemento. En este artículo vamos a
conocer los diversos métodos relacionados con el ciclo de vida, las funciones callback que podemos asociar
a cada uno de ellos y ejemplos que nos ayudarán a comprenderlo todo mucho mejor.

Ciclo de vida de Web Components V1

La mayor parte de los estados del ciclo de vida de un componente Polymer 2 son derivados directamente
del estándar Web Components V1. Es decir, el propio Javascript nativo, el entendido por los navegadores,
es el que nos ofrece mayormente las funciones callback que podemos asociar a un componente.

Los estados del componente a lo largo del ciclo de vida son los siguientes:

constructor: Es el propio constructor de la clase ES6 que se escribe para implementar un custom
element. El constructor se invoca una vez por cada elemento singular creado de un tipo. Es decir, si
tenemos 3 instancias (etiquetas, elementos) del custom element "mi-elemento-personalizado", el
constructor se llamará 3 veces, uno por cada uno.
connectedCallback: Este estado del ciclo de vida ocurre cuando el elemento se inyecta en el DOM

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 40 de 93
Manual de Polymer 2

de la página.
disconnectedCallback: Este estado ocurre cuando el elemento se borra del DOM de la página.
attributeChangedCallback: Este momento del ciclo de vida de los componentes se produce cada
vez que un atributo o propiedad del componente cambia.

Nota: Estos callbacks para hacer cosas durante el ciclo de vida son opcionales. Es decir, si no los
escribes en la implementación del componente simplemente no se realizarán ningunas acciones
específicas en tales momentos.

La mayoría de las veces podrías observar que, al usar un componente, se ejecuta el constructor y
seguidamente el connectedCallback, pero no tiene por qué ser así. Para entenderlo tienes que conocer los
tres mecanismos por los que podríamos crear un componente:

1.- Colocando la etiqueta de ese custom element en el cuerpo de la página

En este caso el constructor del componente se ejecuta y enseguida el connectedCallback, puesto que el
elemento se construye y se inyecta en el contenido de la página en el mismo paso.

<mi-custom-element></mi-custom-element>

2.- Con document.createElement()

Este método de Javascript nativo crea un elemento en la página, que podría ser cualquier elemento del
HTML, pero también un elemento personalizado. En este caso el elemento se crea en la memoria de
Javascript, pero no se inyecta en la página, así que solo se ejecutaría el constructor.

var el1 = document.createElement('mi-custom-element');

3.- Con new, como un objeto de una clase

Ya que los custom elements se definen a partir de clases, nada nos impide crear el componente mediante el
operador "new", igual que hacemos al instanciar objetos en la programación orientada a objetos de toda la
vida. En este caso el componente también se crea sólo en la memoria de Javascript y por ello solo se
ejecutaría el constructor.

var el2 = new MiCustomElement();

Nota: Sobra decir que en este caso usamos el nombre de la clase y no el nombre de la etiqueta, puesto
lo que estamos haciendo es instanciar un elemento de la clase.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 41 de 93
Manual de Polymer 2

Tanto el el caso 2 como en el 3 descritos arriba, si deseas inyectar en la página esos componentes, creados
tan solo en la memoria de Javascript, tendrías que usar los mecanismos conocidos del propio lenguaje para
la manipulación del DOM, como el método appendChild(). En el momento que inyectes ese componente es
en el que se ejecuta finalmente el correspondiente método connectedCallback. Luego veremos ejemplos de
todos estos casos.

Callback específico de Polymer 2: Inicialización del componente

Además de los anteriores métodos callback, Polymer 2 agrega uno adicional denominado "ready", que
seguramente conozcan los desarrolladores que vienen de usar Polymer en su versión 1.x.

ready: este callback para definir acciones durante el ciclo de vida se denomina "One-time
initialization" en la documentación de Polymer 2. Básicamente es como un "connectedCallback",
solo que no se ejecuta más que 1 vez, la primera que se inyecta en el DOM de la página.

La diferencia entonces entre connectedCallback y ready es que un elemento particular podría producir
muchos connectedCallback pero un único ready. Esto podría ocurrir en el caso que un determinado
elemento se coloque en el DOM, luego se quite y se vuelva a colocar. Cada vez que se vuelva a colocar se
ejecuta de nuevo connectedCallback, pero el ready solo se ejecutará la primera vez que se inyectó en la
página.

Nota: "One-time initialization" podría prestarse a confusión, pensando que solo se inicializa una vez,
independientemente del número de instancias del componente. Eso sería incorrecto. Es decir, puedes
tener un número indeterminado de elementos de un custom element determinado. Ready se ejecuta una
tantas veces como número de elementos que hayas creado e incluido dentro del documento o DOM de
la página.

Invocar a super en los métodos callback de Polymer

Es importante que, en todo método callback del ciclo de vida de Polymer, se invoque siempre al método
correspondiente, pero en la clase padre, por medio de "super".

En el caso del constructor ya lo habíamos comentado en artículos anteriores, la necesidad de invocar a


super(). Pero también debemos tener en cuenta hacerlo en el caso de los método callback del estándar, o el
propio "ready", para que Polymer pueda enganchar debidamente el código de nuestros propios callbacks a
las acciones que él debe de realizar para que los procesos de la librería se realicen correctamente.

Solo que en el caso de los métodos callback la llamada a super se realiza con el objeto super y seguido del
método callback que corresponda, por ejemplo: super.disconnectedCallback() o super.ready(). Lo verás más
tarde en un ejemplo en este mismo artículo.

Declaración de propiedades en attributeChangedCallback

Otra cosa que debes saber sobre los callbacks del ciclo de vida en Polymer está relacionada con el

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 42 de 93
Manual de Polymer 2

"attributeChangedCallback", ya que en Polymer 2 sólo se invocará ese callback con las propiedades que
hayas declarado en el objeto "properties". Dicho de otro modo, si el componente sufre un cambio en uno
de sus atributos del HTML no se invocará attributeChangedCallback en el caso que ese atributo no sea una
de sus propiedades declaradas.

Ejemplo de componente y los callbacks del ciclo de vida

Ahora vamos a ver un componente en el que se han implementado todos los callbacks del ciclo de vida que
acabas de conocer. En este componente no se hace nada en particular, solo lo tenemos para ir mandando
mensajes a la consola cada vez que el componente cambia de estado dentro de su ciclo de vida.

<link rel="import" href="../bower_components/polymer/polymer-element.html">

<dom-module id="ciclo-vida">

<template>

<style>

:host {

display: block

</style>

<div>Este es un elemento "ciclo-vida"</div>

</template>

<script>

class CicloVida extends Polymer.Element {

static get is() {

return 'ciclo-vida';

static get properties() {

return {

test: String

};

constructor() {

super();

console.log('Ejecutándose el constructor')

connectedCallback() {

super.connectedCallback();

console.log('Ejecutándose connectedCallback');

disconnectedCallback() {

super.disconnectedCallback();

console.log('Ejecutándose disconnectedCallback');

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 43 de 93
Manual de Polymer 2

attributeChangedCallback(nombre, valorAnterior, valorNuevo) {

super.attributeChangedCallback();

console.log('Ejecutándose attributeChangedCallback', nombre, valorAnterior, valorNuevo);

ready() {

super.ready();

console.log('Ejecutándose ready');

window.customElements.define(CicloVida.is, CicloVida);

</script>

</dom-module>

No debe pasar desapercibido el detalle de las invocaciones a "super" en los callbacks y la declaración
"properties", con la propiedad "test", que es necesaria para que el attributeChangedCallback se llegue a
ejecutar. Si te interesa saber algo más sobre esta llamada a super, por favor, consulta el artículo sobre
herencia en las clases de Javascript ES6.

Para poder ejecutar este componente y asegurarnos que los distintos estados del ciclo de vida se produzcan,
a su tiempo y de manera que podamos percibir cambios en el componente y los mensajes que ocurren,
tenemos que usar el componente con una página HTML que podría tener una forma como esta:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<link rel="import" href="src/ciclo-vida.html">

<title>Uso del componente ciclo-vida y botones para poder producir cambios en el estado</title>

</head>

<body>

<h1>

Uso del componente ciclo-vida

</h1>

<p>Se colocan dos elementos en el body y se generan dos elementos en la memoria de Javascript.</p>

<p>Pulsa además los botones para poder producir cambios en el estado de un elemento y ver los otros mensajes del ciclo de vida.</p>

<ciclo-vida></ciclo-vida>

<ciclo-vida></ciclo-vida>

<button id="anadirAlDOM">Añadir un elemento al DOM</button>

<button id="eliminarDelDOM">Eliminar un elemento del DOM</button>

<button id="cambiarAtributo">Cambiar un atributo de elemento</button>

<script>

var el1 = document.createElement('ciclo-vida');

el1.setAttribute('id', 'el1');

var el2 = new CicloVida();

document.getElementById('anadirAlDOM').addEventListener('click', function() {

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 44 de 93
Manual de Polymer 2

document.body.appendChild(el1);

});

document.getElementById('eliminarDelDOM').addEventListener('click', function() {

document.body.removeChild(document.getElementById('el1'));

});

document.getElementById('cambiarAtributo').addEventListener('click', function() {

el1.setAttribute('test', 'valortest' + Date.now());

});

</script>

</body>

</html>

Te recomendamos poner en marcha estos ejemplos en tu propio proyecto o carpeta de trabajo, para
apreciar el funcionamiento y asimilar el conocimiento contenido en este artículo. Recuerda seguir el Manual
de Polymer 2 para obtener más información sobre el desarrollo con esta estupenda librería basada en Web
Components.

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 12/09/2017
Disponible online en http://desarrolloweb.com/articulos/ciclo-vida-componentes-v1-polymer2.html

Binding en polymer 2
Qué es el binding y cómo lo configuramos en Polymer 2. Tipos de binding bidireccional y
unidireccional. Interoperabilidad entre componentes.

En este artículo del Manual de Polymer 2 vamos a abordar el binding en Polymer 2. Como a estas alturas
muchos lectores tendrán ya claro el concepto de binding, vamos a comenzar directos al grano, ofreciendo
unas pequeñas y rápidas anotaciones para explicar cuál es el funcionamiento general del binding en Polymer
2 y su sintaxis.

Pero si tú todavía no tienes claro qué es el binding no te preocupes, porque en el resto del artículo
ahondaremos en los conceptos para no dejar ni un detalle y de modo que puedas resolver todas tus dudas.

Así pues, vamos a comenzar con explicaciones objetivas y rápidas, que sirvan de referencia para todo el
mundo.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 45 de 93
Manual de Polymer 2

Funcionamiento del binding en Polymer 2

El binding en Polymer funciona siempre transmitiendo los datos de padres a hijos. Un componente puede
transmitir el valor de una de sus propiedades a cualquier elemento del template, así como a otros
componentes que tenga como hijos.

Además el binding es configurable, permitiendo definir si se desea un binding de una dirección o de dos
direcciones. El binding de una dirección es el que transmite de padres a hijos y el binding de dos direcciones
es el que además transmite el valor en dirección contraria: desde el hijo hasta el padre.

Para definir si queremos binding de una dirección y de dos direcciones, utilizamos dos tipos de notaciones
distintas:

La notación de los dobles corchetes "[[]]" significa que se debe implementar binding de una sola
dirección. En este caso el valor bindeado viaja del padre al hijo pero no del hijo al padre.
La notación de las dobles llaves "{{}}" significa binding de dos direcciones. Es decir, el valor
bindeado viaja del padre al hijo y también del hijo al padre.

Nota: Ojo con el binding de dos direcciones, puesto que es un poco más pesado para la aplicación, en
términos de tiempo de procesamiento. Por eso en muchas ocasiones es preferible usar bindeo de una
sola dirección y usar mecanismos como los eventos para producir el aviso a los padres cuando los hijos
desean cambiar el valor de las propiedades. Hablaremos de esto más adelante en otros ejemplos cuando
hayamos abordado el tema de los eventos en Polymer.

De momento es todo lo que te vamos a contar en el presente artículo sobre el binding en Polymer. Solo
debes saber además que para que se produzca un binding ascendente en Polymer, aparte de usar las dobles
llaves, necesitas que el componente que debe avisar al padre tenga definida la propiedad con el valor
"notify" a "true". Hablaremos de esto más adelante también con otros ejemplos.

Nota: Para que quede claro, con respecto al binding de dos direcciones, debes entender que por mucho
que tú lo uses al declarar el bindeo en el template, Polymer no siempre lo implementará y te hará un
binding de una única dirección. Por ejemplo, también te ocurrirá cuando bindeas al contenido de una
etiqueta HTML párrafo (etiqueta P). Por mucho que uses dobles llaves no servirá para nada, ya que ese
párrafo no está preparado para avisar al padre hipotéticos cambios.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 46 de 93
Manual de Polymer 2

Si no tienes claro el concepto de binding o deseas ver ejemplos de binding en Polymer, sigue leyendo.

Qué es el binding

El binding es una herramienta base de muchas librerías y frameworks. Simplemente es un enlace, para
asociar un mismo dato a diversos integrantes de una aplicación, de tal modo que si uno de ellos lo cambia,
su valor cambie en los otros elementos que tienen ese dato bindeado.

El binding nos ahorra programar más de la cuenta, pues el propio Polymer será el encargado de hacer viajar
el dato bindeado de un lugar a otro. Esto evita que tengamos que estar suscribiendonos a eventos, para
saber en qué momento se modifica un dato y así realizar la operación de escritura manualmente en los
elementos u objetos que lo comparten.

Básicamente encontraremos binding en dos situaciones. Prefiero verlas por separado, aunque realmente
podríamos decir que es lo mismo con distintos matices.

Binding del componente al template

El caso más sencillo de binding se produce desde las propiedades de un componente hacia el template. Este
ejemplo ya lo hemos observado en casos anteriores del Manual de Polymer 2, como en el componente del
estado de ánimo del artículo de Propiedades y estado de los componentes en Polymer 2.

Al tener una propiedad declarada:

static get properties() {

return {

propiedadComponente: {

type: String,

value: 'Valor predeterminado'

};

Podremos bindearla, para mostrar su estado actual en el template:

<template>

<p>

Este valor está bindeado: "[[propiedadComponente]]"

</p>

</template>

El valor de la propiedad "propiedadComponente" se volcará en el párrafo de este template, mostrando


automáticamente el nuevo valor cuando el dato cambia.

Nota: La notación de los corchetes "[[]]" en este caso produce un binding de una sola dirección.
Aunque en este caso, al bindear a un texto de un template realmente no podría existir binding de dos

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 47 de 93
Manual de Polymer 2

direcciones, por lo que tampoco tendría mucho sentido usar las dobles llaves.

Binding entre componentes

Además puede darse el binding entre diversos componentes. Por ejemplo, lo tenemos aquí:

<template>

<paper-input label="¿cómo te encuentras?" value="{{miAnimo}}"></paper-input>

<estado-animo animo="[[miAnimo]]"></estado-animo>

</template>

En este template tenemos dos ejemplos de binding entre componentes y en uno hemos usado bindeo de
una dirección y en otro bindeo de dos direcciones. Todo tiene su sentido.

Por un lado tenemos un paper-input, que es un campo de texto donde se puede escribir una cadena de
caracteres. El valor del campo de texto se está escribiendo en la propiedad "miAnimo", por medio de un
binding escrito sobre el atributo "value" del paper-input.

Nota: en este caso, con la notación de las dobles llaves "{{}}" estamos produciendo un binding de dos
direcciones: value="{{miAnimo}}". Aquí es necesario el binding de dos direcciones para que, cuando
alguien escriba algo en el campo de texto, el valor nuevo que se ha escrito viaje automáticamente al
padre.

Como segundo ejemplo de binding tenemos la propiedad "miAnimo" bindeada al componente "estado-
animo". Eso indica que, cada vez que cambie "miAnimo" porque el usuario escriba otra cosa en el paper-
input, se actualizará el valor bindeado al componente "estado-animo".

Nota: en este nuevo caso tenemos un binding de una dirección: animo="[[miAnimo]]". En este caso es
suficiente de una dirección porque el componente estado-animo no tiene posibilidad de cambiar el valor
de la propiedad bindeada. Y aunque lo cambiase, el componente padre no necesita enterarse de nada.

Código completo de este ejercicio

Para acabar, vamos a ver el código completo del componente que hemos creado para explicar el binding.
En realidad es una modificación del ejemplo que explicamos en el anterior artículo, donde hablamos sobre
la instalación de Polymer 2 y su CLI.

<link rel="import" href="../../bower_components/polymer/polymer-element.html">

<link rel="import" href="../../bower_components/paper-input/paper-input.html">

<link rel="import" href="../estado-animo.html">

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 48 de 93
Manual de Polymer 2

<dom-module id="test-cli-app">

<template>

<style>

:host {

display: block;

</style>

<estado-animo animo="{{estadoAnimo}}"></estado-animo>

<paper-input label="¿cómo te encuentras?" value="{{estadoAnimo}}"></paper-input>

Este valor está bindeado: "[[estadoAnimo]]"

</template>

<script>

class TestCliApp extends Polymer.Element {

static get is() { return 'test-cli-app'; }

static get properties() {

return {

estadoAnimo: {

type: String,

value: 'de rechupete'

};

window.customElements.define(TestCliApp.is, TestCliApp);

</script>

</dom-module>

Obviamente, un tema tan importante como el binding incluye muchas otras cosas que no hemos abordado
en este artículo. Pero no te preocupes, con lo que hemos visto aquí podremos ir funcionando bien, hasta
que lleguemos a un nivel más avanzado en el manual de Polymer 2.

Más adelante en la sección de binding podremos aprender muchas otras cosas interesantes, como hacer
componentes que avisen a los padres de cambios en sus propiedades, bindear a atributos nativos de
elementos de HTML, etc.

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 19/09/2017
Disponible online en http://desarrolloweb.com/articulos/binding-polymer2.html

Introducción a los eventos en Polymer 2


Aprende lo básico de los eventos en Polymer 2: Cómo definir manejadores de eventos y asociarlos
a elementos dependientes de un componente Polymer.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 49 de 93
Manual de Polymer 2

El mundo de los eventos en Polymer es bastante rico y además ha cambiado en algunas cosas en lo que
respecta a su versión predecesora, por lo que tendremos que prestar bastante atención incluso si venimos de
Polymer 1.x. La novedad principal es que en Polymer 2 se usa más el propio Javascript nativo para cosas en
las que antes existían mecanismos proveídos por la propia librería (Recuerda: "UseThePlatform").

Sin embargo, en este artículo vamos a observar algunas cosas sencillas sobre eventos, que nos permitan
tener las bases para ir realizando ejemplos, en lo sucesivo del Manual de Polymer 2, en los que podamos
usar distintos tipos de eventos y asociar manejadores. En resumen, nos centraremos por ahora en la
declaración de los eventos dentro del propio template y usaremos eventos básicos, puesto que los eventos
de gestos requieren cargar mixins, de los que todavía no hemos hablado.

Además, para los que vienen de Polymer 1.x ofreceremos algunas de las claves principales que deben
conocer para saber qué diferencias encontrarán en el tratamiento de eventos en la versión 2 de la librería.

Asociar un evento a un elemento en línea

A la hora de escribir un template podemos asociar una función manejadora de evento en cualquier elemento
del shadow dom del componente. Para ello simplemente usaremos un atributo "on-", seguido del nombre
del evento que queramos definir su manejador. Ese atributo tendrá como valor el nombre del método
manejador del evento que se desea asociar.

Por ejemplo, encontraremos un código como este para definir un manejador de evento frente a un clic
sobre un botón.

<button on-click="incrementaClic">Clic para contar</button>

Declaración de un manejador de evento

El manejador del evento en un componente de Polymer corresponde con un método de la propia clase del
componente. El método lo podemos definir como cualquier otro método dentro de la clase ES6.

incrementaClic() {

// código a ejecutar como manejador del evento

El manejador recibe el objeto evento, del que podemos obtener información diversa sobre el tipo de evento
que se acaba de producir. Ese objeto evento será siempre el primer parámetro del manejador.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 50 de 93
Manual de Polymer 2

incrementaClic(e) {

console.log('Objeto evento', e)

Ejemplo de tratamiento de eventos sencillos en un componente

Ahora vamos a ver el código de un componente sencillo para aprender a trabajar con lo básico de eventos.
Este componente me informa de las veces que he hecho clic en un botón, por medio de un contador que se
incrementa con cada clic. Además encontraremos otro botón que permite resetear el contador, volviendo su
valor a cero.

<link rel="import" href="../../bower_components/polymer/polymer-element.html">

<dom-module id="cuenta-clics">

<template>

<style>

:host {

display: block;

padding: 5px;

border: 1px solid orange;

margin-bottom: 5px;

p {

margin-top: 0;

padding: 5px;

background-color: darkorange;

color: white;

</style>

<p>

Llevas [[contador]] clics

</p>

<button on-click="incrementaClic">Clic para contar</button>

<button on-click="resetear">Resetear la cuenta</button>

</template>

<script>

class CuentaClics extends Polymer.Element {

static get is() {

return 'cuenta-clics';

static get properties() {

return {

contador: {

type: Number,

value: 0

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 51 de 93
Manual de Polymer 2

constructor() {

super();

incrementaClic(e) {

this.contador++;

console.log('Objeto evento', e)

resetear() {

this.contador = 0;

window.customElements.define(CuentaClics.is, CuentaClics);

</script>

</dom-module>

Notas adicionales sobre eventos

De momento vamos a quedarnos con lo aprendido hasta este momento, pero para que no te sientas perdido
si vienes de Polymer 1.x quiero ofrecer algunas otras claves:

Usar addEventListener de Javascript

En Polymer se recomienda usar el propio Javascript para crear tus eventos. Por ejemplo, si quieres crear un
evento que afecte a todo el host (el componente completo, la etiqueta que engloba todo el Shadow DOM
que podamos tener dentro del elemento personalizado) podrías crearlo directamente con
this.addEventListener().

En este código vemos cómo definir el evento sobre el host, asociando el manejador en el método callback
ready.

ready() {

super.ready();

this.addEventListener('click', () => {

console.log('yeahhh este evento se asocia al componente completo');

})

Eventos de gestos

Los eventos de gestos ahora no están incluidos "de casa", por eso no te funcionará el evento on-tap en un
componente básico. Hay un mixin llamado Polymer.GestureEventListeners que da soporte a los eventos de
gestos y que tendremos que heredar en el componente donde los queramos usar.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 52 de 93
Manual de Polymer 2

Nota: Los mixins sirven para hacer lo que sería algo parecido a la herencia múltiple. Básicamente sirven
para heredar código sin necesidad de que el mixin esté en el extends. Son necesarios porque Javascript
no tiene herencia múltiple. Pero lo más importante que ya te adelantamos también, los mixins en
Polymer 2 son los sustitutos a lo que conocíamos por "behaviors" en Polymer 1.x.

Como decía, no me quiero meter todavía en este tema, pero es bueno que se sepa ya. Encuentras más
información de momento en la documentación.

Eliminado this.fire()

Otra cosa que echarás en falta si vienes de Polymer 1 es que se ha eliminado el método fire que existía en
todos los elementos de Polymer, útil para lanzar eventos personalizados. Ahora usas el método nativo de
Javascript dispatchEvent. Más adelante pondremos ejemplos.

Conclusión

Como ves, lo básico de eventos es muy sencillo, ya que podemos definir los eventos de manera declarativa y
los métodos manejadores son también muy rápidos de implementar. En ellos tenemos acceso a todas las
propiedades y recursos del componente para poder reaccionar de la manera que haga falta.

Sin embargo, nos hemos quedado solamente en lo fundamental y además hay diferentes usos necesarios de
aprender en Polymer 2, sobre los que tendremos que volver en el futuro en varios artículos y ejemplos.
Nuestro objetivo ahora era simplemente dar unos conocimientos fundamentales para poder apoyarnos en
ellos en futuros ejercicios y artículos. Os pedimos un poco de paciencia porque todo se verá a su debido
tiempo.

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 27/09/2017
Disponible online en http://desarrolloweb.com/articulos/introduccion-eventos-polymer2.html

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 53 de 93
Manual de Polymer 2

Propiedades en componentes Polymer 2


al detalle

En la próxima serie de artículos vamos a detallar cómo funciona el sistema de propiedades en componentes
desarrollados con Polymer 2. Estudiaremos asuntos importantes para poder crear nuestros custom elements
sacando partido a las posibilidades de la librería, como la serialización y deserialización de propiedades a
atributos, los tipos de propiedades disponibles en el librería, junto con ejemplos destacados de componentes
donde seguir practicando.

Tipos de propiedades y deserialización de atributos en componentes


Polymer
Propiedades en Polymer 2 y los tipos de datos posibles, explicando los mecanismos de
deserialización de atributos para recibir los valores de las propiedades.

En Polymer 2, de manera similar a su predecesor Polymer 1, existe la posibilidad de trabajar de una manera
ágil con propiedades de los componentes, así como asignar valores desde fuera de éstos, de manera
declarativa en el propio HTML. Ésto no debe ser nuevo para ti, puesto que las propiedades son una de las
principales herramientas con las que contamos para el desarrollo basado en componentes y ya hemos
trabajado con ellas anteriormente.

En esta ocasión vamos a ahondar sobre el tema de las propiedades, explicando los tipos de datos que
puedes asignarles y cómo se deserializan valores en las etiquetas de los componentes. Recuerda consultar el
artículo de introducción a las propiedades y estado de los componentes para encontrar información más
básica y general.

Tipos de datos en las propiedades

Al declarar propiedades podemos indicar el tipo de datos que vamos a usar en esa propiedad, de modo que
en el momento de su creación Polymer se ocupará por asignar ese tipo a la variable.

Como sabes, Javascript es un lenguaje con tipado dinámico, por lo que una variable puede cambiar de tipo

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 54 de 93
Manual de Polymer 2

con el tiempo, ya sea porque el programador lo requiera o porque algún despiste en el código produzca ese
cambio de tipo en el tiempo de ejecución. De modo que Polymer nos asegurará que la propiedad tenga
inicialmente un tipo, pero no puede asegurarnos que lo mantenga durante toda la ejecución de la aplicación,
pues es algo que depende más de cómo la hayas programado.

En el siguiente código tenemos dos propiedades declaradas, miNumero y miString. Esas propiedades
tendrán los tipos definidos en la declaración que puedes ver a continuación.

static get properties() {

return {

miNumero: Number,

miString: {

type: String,

value: 'Esto es una cadena'

},

Al declarar las propiedades podemos simplemente indicar el tipo, como es el caso de "miNumero" en el
código anterior. Pero, si además queremos declarar otras cosas sobre la propiedad, como su valor por
defecto, una función observadora, etc., entonces necesitas pasar a una declaración compuesta en notación
de objeto, como el caso de "miString".

Deserialización de los atributos en valores de propiedades

Para entendernos, ahora vamos a llamar atributos a los valores que se colocan en una etiqueta HTML de un
componente, como por ejemplo "mi-atributo" en el siguiente código:

<mi-componente mi-atributo="valor del atributo"></mi-componente>

Una propiedad es algo interno del componente y Polymer nos ofrece de manera automática el traspaso del
valor de un atributo en su correspondiente propiedad.

Mayúsculas y minúsculas en atributos y propiedades

Solo debes tener en cuenta que en HTML no existe distinción entre mayúsculas y minúsculas, y sin embargo
Javascript sí que lo tiene en cuenta. Por ello al trabajar con nombres de atributos y propiedades hay que ir
con cuidado especial.

La propiedad, al ser algo del lenguaje Javascript, se suele escribir con notación "CamelCase", colocando las
primeras letras de la segunda y siguientes palabras en mayúscula. Para adaptar el CamelCase en el HTML se
utilizan guiones, separando las distintas palabras. Por ejemplo la propiedad "miNumero" se correspondería
con el atributo "mi-numero" en el HTML.

Nota: Es un error frecuente olvidarse los guiones en el HTML y escribir los atributos con CamelCase.
En este caso no se realizará la correspondencia a la propiedad con su nombre CamelCase, sino a su
nombre con minúsculas. Por ejemplo el atributo HTML "ciudadOrigen" se haría corresponder con la

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 55 de 93
Manual de Polymer 2

propiedad Polymer "ciudadorigen".

Tipos de datos en la deserialización

El proceso por el que se traspasan los valores del HTML a las propiedades es la deserialización y en él se
intentará corresponder el valor del atributo con el tipo de dato indicado en la declaración de la propiedad.

Esto es importante porque todos los datos colocados como valores de atributos en el HTML son cadenas
de texto. HTML no distingue si lo que se ha colocado como valor de un atributo es una cadena, un número
o un boleano y sin embargo, Polymer nos hará el trabajo de corresponder y transformar aquella información
al tipo correcto.

Cadenas (String): Aquí Polymer no realiza ningún trabajo especial, puesto que los valores de los
atributos son siempre cadenas.
Números (Number): Polymer se encarga de convertir la cadena en un valor numérico, haciendo lo
posible porque esa conversión sea lógica. Convierte por ejemplo la cadena "4" por el número 4.
Convierte la cadena "092" por el número 92. Aunque algo como "x665" no lo podría convertir en
un número y otorgará a la propiedad el valor "NaN" (not a number).
Boleanos (Boolean): En este caso no importa el valor del atributo, sino simplemente su presencia.
En el caso que el atributo se encuentre en la etiqueta, entonces la propiedad tendría valor asignado
como "true". Si el atributo no está presente, la propiedad nacerá con el valor "false" (a no ser que se
le indique otro valor predeterminado).
Arrays y objetos (Array / Object): Para estos dos tipos de datos los valores de los atributos se
tienen que indicar con notación JSON. En este caso es importante tener en cuenta que en un JSON
las comillas válidas son las comillas dobles (") y por tanto no nos queda otro remedio de colocar el
valor del atributo HTML con comillas simples. Luego verás un ejemplo.
Fechas (Date object): Polymer tratará de convertir la fecha en un objeto de la clase Date de
Javascript. Ten en cuenta que debes usar un formato de fecha apropiado como valor de atributo,
como 2017-09-01.

Ejemplo de componente y declaración de propiedades

Con lo aprendido en este artículo vamos a mostrar el código de un componente que podríamos tener para
practicar con diferentes tipos de propiedades.

Nota: Encontrarás algunas cosas de las que no hemos hablado todavía, como un template de repetición,
que usamos para recorrer los elementos de un array. La declaración de eventos diversos. O un $
misterioso en un binding sobre un atributo hidden (hidden$) que en este caso sirve para ocultar o
mostrar elementos dependiendo de una propiedad boleana.

<link rel="import" href="../../bower_components/polymer/polymer-element.html">

<link rel="import" href="../../bower_components/polymer/lib/elements/dom-repeat.html"

>

<dom-module id="deserializacion-tipos">

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 56 de 93
Manual de Polymer 2

<template>

<style>

:host {

display: block

</style>

<div on-click="mostrarTipoMiString">[[miString]]</div>

<div on-click="mostrarTipoMiNumero">[[miNumero]]</div>

<div hidden$="[[miBoleano]]" on-click="mostrarTipoMiBoleano">miBoleano es false</div>

<div hidden$="[[!miBoleano]]" on-click="mostrarTipoMiBoleano">miBoleano es true</div>

<template is="dom-repeat" items="[[miArray]]">

[[item]]

</template>

<div>

Datos del objeto propiedad1: [[miObjeto.prop1]], propiedad2: [[miObjeto.prop2]], propiedad3: [[miObjeto.prop3]]

</div>

<div on-click="mostrarTipoMiFecha">Fecha: [[miFecha]]</div>

</template>

<script>

class DeserializacionTipos extends Polymer.Element {

static get is() {

return 'deserializacion-tipos';

static get properties() {

return {

miString: {

type: String,

value: 'Esto es una cadena'

},

miNumero: {

type: Number

},

miBoleano: Boolean,

miArray: Array,

miObjeto: Object,

miFecha: Date

};

constructor() {

super();

mostrarTipoMiNumero() {

console.log('Tipo es: ', typeof(this.miNumero));

mostrarTipoMiBoleano() {

console.log('Tipo es: ', typeof(this.miBoleano));

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 57 de 93
Manual de Polymer 2

mostrarTipoMiString() {

console.log('Tipo es: ', typeof(this.miString));

mostrarTipoMiFecha() {

console.log('Tipo es: ', typeof(this.miFecha), ' y valor: ', this.miFecha);

window.customElements.define(DeserializacionTipos.is, DeserializacionTipos);

</script>

</dom-module>

En el componente se agregaron unos eventos "click" que nos sirven para mandar mensajes a la consola en
los que mostramos el tipo de datos que tienen las propiedades en el componente.

Ahora puedes apreciar el código que tendríamos para usar este componente, enviando los valores de los
atributos en el código HTML. Realmente no tiene mucho misterio, pero sobre todo resulta interesante ver
cómo se han definido los valores de tipo array y tipo objeto en formato JSON.

<deserializacion-tipos

mi-numero="090"

mi-boleano

mi-array="[3, 67, 9]"

mi-objeto='{"prop1": "valor1", "prop2": "valor2", "prop3": "valor3"}'

mi-fecha="1975-02-21"

></deserializacion-tipos>

Nota: Recuerda que para funcionar tendrías que importar como siempre el componente, usando el
correspondiente "import".

Insistimos en tomar en cuenta las comillas dobles en un JSON. Observa cómo el atributo "mi-objeto" tiene
comillas simples para indicar su valor. En el caso del valor de "mi-array", aunque el valor es otro JSON, nos
hemos tomado la licencia de usar comillas dobles, dado que no hemos necesitado usar cadenas dentro del
JSON.

Deserialización personalizada de atributos

Una utilidad interesante en Polymer 2 es la deserialización personalizada, que permite al desarrollador


sobreescribir el procedimiento para deserializar un valor de un tipo de atributo.

Vamos a suponer que en un componente debemos reconocer los tipos "Date" con valores que admitan el
formato de fechas en español. En este caso no nos sirve el deserializador de Date disponible, por lo que
podemos sobreescribirlo, rescribiendo simplemente el método de Polymer _deserializeValue(value, type).
Lo vamos a ver con un ejemplo de un nuevo componente:

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 58 de 93
Manual de Polymer 2

<link rel="import" href="../../bower_components/polymer/polymer-element.html">

<dom-module id="deserializacion-personalizada">

<template>

<style>

:host {

display: block

</style>

<div on-click="mostrarTipoMiFechaEspanola">Fecha: [[miFechaEspanola]]</div>

</template>

<script>

class DeserializacionPersonalizada extends Polymer.Element {

static get is() {

return 'deserializacion-personalizada';

static get properties() {

return {

miFechaEspanola: Date

};

constructor() {

super();

_deserializeValue(value, type) {

if (type == Date) {

return this.fechaEspanolaToDate(value);

return super._deserializeValue(value, type);

fechaEspanolaToDate(valor) {

console.log('parseando a fecha: ', valor);

//realizaría el trabajo de comprobar el formato y parsear...

return 'devuelvo el valor que toque';

mostrarTipoMiFechaEspanola(){

console.log('Tipo es: ', typeof(this.miFechaEspanola), ' y valor: ', this.miFechaEspanola);

window.customElements.define(DeserializacionPersonalizada.is, DeserializacionPersonalizada);

</script>

</dom-module>

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 59 de 93
Manual de Polymer 2

En este componente tenemos una propiedad llamada "miFechaEspanola" que es de tipo Date.

Al sobreescribir _deserializeValue() preguntamos si el tipo es Date, en cuyo caso lo dirigimos por una
función propia, que en este caso hemos llamado fechaEspanolaToDate(). Esa función se encargaría de
realizar el trabajo necesario, devolviendo el valor deserializado.

Nota: en nuestro caso el código de la función fechaEspanolaToDate() es solo un mensaje para la


consola y un return de una cadena. Lógicamente no es correcto, pues tendría que hacer el trabajo de
convertir la cadena en un objeto Date correcto. Pero ese algoritmo no es el objetivo de este artículo.

Incluso podríamos crearnos nuestro propio tipo personalizado con una clase ES6, por ejemplo:

class TipoPersonalizado {

//aquí el código de un nuevo tipo inventado, definido por medio de una clase ES6

Esa clase ahora nos permite definir propiedades de este tipo personalizado.

static get properties() {

return {

miFechaEspanola: TipoPersonalizado

};

Y ahora para deserializar este tipo personalizado nuevo, tenemos que sobreescribir _deserializeValue(), igual
que antes.

_deserializeValue(value, type) {

if (type == Date) {

return this.fechaEspanolaToDate(value);

if (type = TipoPersonalizado) {

return this.parsearOtraCosa(value);

return super._deserializeValue(value, type);

Eso es todo de momento. Hemos hablado mucho de los types en las propiedades. Es un asunto importante,
pero hay muchas otras funcionalidades y posibilidades en las properties de Polymer que todavía no hemos
explicado y que veremos en los próximos artículos del manual de Polymer 2.

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 18/10/2017

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 60 de 93
Manual de Polymer 2

Disponible online en http://desarrolloweb.com/articulos/tipos-datos-deserializacion-atributos-polymer.html

Funcionalidades incorporadas en las propiedades de Polymer 2


Qué funcionalidades tenemos disponibles para la configuración de propiedades en los
componentes de Polymer 2.

Existe un rico conjunto de funcionalidades en las propiedades de los componentes, incorporadas de casa en
Polymer 2, que nos servirán para satisfacer las más variadas necesidades en el desarrollo de custom elements
y de aplicaciones basadas en Web Components. Algunas de ellas ya las hemos visto anteriormente en el
Manual de Polymer 2. Por ejemplo, en el artículo anterior describimos con detalle cómo funciona la
declaración "type" en las propieades, aunque en este artículo las explicaremos todas, para que tengas una
visión global de las posibilidades.

Si vienes de Polymer 1.x, hay que decir que las propiedades de Polymer 2 tienen las mismas funcionalidades
que ya conoces, por lo que el presente artículo te servirá más bien para refrescar los conocimientos y
acceder a nuevos ejemplos de componentes realizados según las guías de Web Components V1 y Polymer
2.

Configuraciones posibles en propiedades de Polymer 2

Comenzamos con un listado de las funcionalidades configurables en las propiedades de los componentes.

type: Sirve para indicar el tipo (Boolean, Number, String, Array, Object y la menos conocida Date)
Sobre este asunto hemos hablado suficiente en el pasado artículo sobre los tipos y deserialización de
atributos.
value: Sirve para definir el valor predeterminado de una propiedad. Si se indica, se usará para
inicializar esa propiedad, aunque a la hora de usar el componente mandará la posible inicialización
que se realice en el atributo HTML del componente asociado con esa propiedad. El valor también
se puede calcular por medio de una función, que se invocará si es necesario en la inicialización del
componente. Se usará el valor de devolución de la función para inicializar la propiedad. Además,
para propiedades de tipo Array y Object, si queremos que exista una copia del array o el objeto para
cada elemento generado, tenemos que producir ese array u objeto en una función, devolviendo el
valor a inicializar con el correspondiente return.
reflectToAttribute: Sirve para que el valor de la propiedad actualice el valor de la propiedad en el
elemento. Por defecto esto no ocurre, por lo que, si se cambia el valor de una propiedad, no se
refleja en el HTML del componente host. Si queremos que se actualice el atributo en la etiqueta

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 61 de 93
Manual de Polymer 2

HTML se debe marcar con true reflectToAttribute.


readOnly: Si lo configuramos como true, el valor de esa propiedad no se puede alterar desde fuera,
vía binding.
notify: esta configuración permite que el componente notifique a los padres mediante binding
cualquier cambio de la propiedad. Es una configuración muy importante para que los elementos que
crees soporten binding de dos direcciones. Por defecto está a false y en ese caso, aunque el
componente modifique internamente una propiedad, su valor no viajará al padre por binding,
independientemente que usemos las dobles llaves al declarar el bindeo en el template.
computed: es otra de las más importantes configuraciones, que permite hacer propiedades que
tiene valores que serán calculados por una función. Se utilizan muchísimo, ya que muchas veces los
valores de propiedades son el resultado de realizar un cálculo. Para definir una propiedad
computada usamos una función, que recibe los valores necesarios para realizar el cálculo, que deben
ser otras propiedades del componente. Polymer ya automatiza el procedimiento para que, cuando
cambian los parámetros de entrada en el cómputo, se invoque de nuevo la función, de modo que
siempre las propiedades computadas tengan el valor actualizado.
observer: También es extremadamente útil, ya que permite definir una función que se ejecutará
cuando se produzcan cambios en el valor de una propiedad, facilitando enormemente la
programación reactiva. Cada vez que una propiedad se altere el componente reacciona por los
observers y realiza todas las operaciones que ese cambio deba producir.

De todas estas configuraciones de propiedades iremos realizando ejemplos a lo largo del manual. Muchas de
ellas las veremos en repetidas ocasiones y las analizaremos de manera más detallada en futuros artículos.

Ejemplo de declaración de propiedades

Aunque hemos visto anteriormente otros componentes en los cuales hemos incorporado propiedades,
vamos a ver un nuevo ejemplo de declaración de custom element Polymer 2 en el que tenemos un listado
amplio de propiedades.

En este caso tenemos un supuesto componente que muestra un contacto. El nombre es "persona-contacto"
y básicamente lo hemos hecho para tener varios tipos de propiedades con diversas inicializaciones. Es
interesante fijarse en la inicialización de las propiedades de tipo "Array" y tipo "Objetc", en las que tenemos
necesariamente que crear una función que hace el return del nuevo array de teléfonos de contacto o el
objeto con los datos complejos de su dirección.

<link rel="import" href="../../bower_components/polymer/polymer-element.html">

<dom-module id="persona-contacto">

<template>

<style>

:host {

display: block

</style>

<h1>

Contacto {{nombre}} {{apellidos}}

</h1>

<p>

... dejamos como ejercicio crear un template adecuado con el que mostrar de manera ordenada sus propiedades

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 62 de 93
Manual de Polymer 2

</p>

</template>

<script>

class PersonaContacto extends Polymer.Element {

static get is() {

return 'persona-contacto';

static get properties() {

return {

nombre: {

type: String,

value: ''

},

apellidos: {

type: String,

value: ''

},

direccion: {

type: Object,

value: function() {

return {

via: '',

numero: '',

codigoPostal: '',

ciudad: ''

};

},

telefonos: {

type: Array,

value: function() {

return [];

},

FechaNacimiento: Date,

email: {

type: String,

value: ''

},

identificadorGrupo: {

type: Number,

value: 0

},

activo: {

type: Boolean,

value: true

};

constructor() {

super();

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 63 de 93
Manual de Polymer 2

window.customElements.define(PersonaContacto.is, PersonaContacto);

</script>

</dom-module>

Queda bastante por aprender de las propiedades, pero imagino que ya vamos teniendo las nociones básicas
para entender cómo funcionan. En los futuros artículos haremos nuevos ejemplo en los que trabajaremos
con otras configuraciones posibles para las propiedades.

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 02/11/2017
Disponible online en http://desarrolloweb.com/articulos/funcionalidades-propiedades-polymer-2.html

Ejemplo de uso de reflectToAttribute en Polymer 2


En este artículo vamos a mostrar un ejemplo que nos ilustre el uso de la configuración
reflectToAttribute en componentes de Polymer 2.

En un pasado artículo del Manual de Polymer explicamos de manera general el listado de posibles
configuraciones en propiedades de Polymer 2. Vimos que hay muchas posibilidades y algunas de ellas
quedaron pendientes de una explicación más detallada.

Ahora vamos a practicar con una de las configuraciones de propiedad más simples, reflectToAttribute.
Como hemos mencionado anteriormente, sirve para que la etiqueta host refleje en sus atributos los cambios
que se produzcan en las propiedades del componente. Recuerda, el atributo es lo que escribimos en una
etiqueta HTML y la propiedad es lo que controlamos desde Javascript.

Podemos tener un componente que sea así:

<componente-complejo></componente-complejo>

Al usarlo no indicamos ningún atributo, pero quizás dentro del componente complejo tenemos decenas de
propiedades para controlar su estado. Esas propiedades generalmente se gestionan dentro del componente y
los valores actuales no se reflejan modificando los atributos en la etiqueta host.

Nota: Por etiqueta host puedes entender la etiqueta que escribes para usar un componente. Dentro del
componente podemos tener un template con una serie de etiquetas en lo que llamamos el Shadow
DOM, pero el componente en si se usa con una sola etiqueta, con el nombre del elemento. Esa etiqueta
que se coloca en el HTML para usar el componente es la etiqueta host.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 64 de 93
Manual de Polymer 2

Ejemplo de componente con propiedades reflectToAttribute

Entendido esto, podemos pasar a ver el uso de la configuración reflectToAttribute, que modifica el
comportamiento del componente para reflejar el estado de las propiedades que deseemos que se vean desde
fuera.

Para poner en marcha esta funcionalidad hemos creado este elemento:

<link rel="import" href="../../bower_components/polymer/polymer-element.html">

<dom-module id="uso-reflecttoattribute">

<template>

<style>

:host {

display: block

</style>

Este es el valor que debe verse en el atributto del host: [[reflejada]]

<button on-click="cambiarValor">Haz clic para cambiar el valor (que se reflejará en el atributo)</button>

</template>

<script>

class TipoPersonalizado {

//aquí el código de un nuevo tipo inventado

class UsoReflecttoattribute extends Polymer.Element {

static get is() {

return 'uso-reflecttoattribute';

static get properties() {

return {

reflejada: {

type: String,

value: 'Me reflejo!!',

reflectToAttribute: true

};

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 65 de 93
Manual de Polymer 2

constructor() {

super();

cambiarValor() {

this.reflejada = Date.now();

window.customElements.define(UsoReflecttoattribute.is, UsoReflecttoattribute);

</script>

</dom-module>

Ahora, para usar el componente podríamos tener perfectamente este HTML:

<uso-reflecttoattribute></uso-reflecttoattribute>

Si lo ponemos en marcha, cuando el componente sufre el upgrade, veremos cómo en el instante aparece el
atributo "reflejada" con su valor predeterminado. Al inspeccionar el HTML con las herramientas de
desarrolladores veríamos esto (fíjate la etiqueta host "uso-reflecttoattribute"):

El componente además tiene un botón que, al pulsarse, cambia el estado de la propiedad, con lo que
veríamos que el nuevo estado también se refleja como atributo en la etiqueta host.

Serialización de las propiedades reflejadas con reflectToAttribute

Es interesante saber que, cuando se refleja una propiedad en un atributo del componente ocurre una
serialización del valor de la propiedad. Esa serialización se realiza para convertir aquel valor de la propiedad
en un string, ya que los valores de los atributos en HTML solo aceptan cadenas.

Nota: este paso, la serialización de las propiedades reflejadas, es básicamente el opuesto de la


deserialización que hemos detallado en el artículo sobre Tipos de datos en deserialización de atributos.

Al serializar se realizan unas operaciones de conversión a cadena que dependen del tipo (type) de la
propiedad declarada. Por ejemplo un Date o Number se serializan con el método toString() o el array y
object se serializan con JSON.stringify(). Sin embargo nosotros podemos alterar la serialización
predeterminada o crear propiedades de tipos personalizados que tengan serializaciones determinadas por

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 66 de 93
Manual de Polymer 2

nuestro propio código. Para ello tenemos que sobreescribir el método _serializeValue(value) en nuestro
componente.

A continuación puedes ver un ejemplo de sobreescritura del método:

_serializeValue(value) {

if (typeof(value) == 'number') {

return '--' + value + '--';

if (value instanceof Cliente) {

return value.nombreContacto + ' de ' + value.empresa + ' (' + value.cif + ')';

return super._serializeValue(value);

En este ejemplo encontramos un primer condicional if que detecta si se debe serializar una propiedad de
tipo Number, en cuyo caso no se usará la serialización predeterminada de Polymer, sino una personalizada
por nosotros mimos. Como puedes apreciar, lo que se devuelve es una cadena con el número embutido
entre dos guiones.

En el segundo condicional se detecta si lo que se tiene que serializar es un objeto de la clase Cliente, en cuyo
caso se hace una serialización personalizada, en una cadena en la que se visualizan los datos del cliente.

Por último, para cualquier otro tipo de dato, se llama al método de serialización de la clase padre.

Este ejemplo lo puedes ver en uso en el siguiente componente.

<link rel="import" href="../../bower_components/polymer/polymer-element.html">

<dom-module id="uso-reflecttoattribute-serialize">

<template>

<style>

:host {

display: block

</style>

</template>

<script>

class Cliente {

constructor(nombre, empresa, cif) {

this.nombreContacto = nombre;

this.empresa = empresa;

this.cif = cif;

class UsoReflecttoattributeSerialize extends Polymer.Element {

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 67 de 93
Manual de Polymer 2

static get is() {

return 'uso-reflecttoattribute-serialize';

static get properties() {

return {

numeroReflejado: {

type: Number,

value: 992,

reflectToAttribute: true

},

cliente: {

type: Cliente,

value: function() {

return new Cliente('Miguel Angel Alvarez', 'EscuelaIT', 'B99222000');

},

reflectToAttribute: true

};

constructor() {

super();

cambiarValor() {

this.reflejada = Date.now();

_serializeValue(value) {

if (typeof(value) == 'number') {

return '--' + value + '--';

if (value instanceof Cliente) {

return value.nombreContacto + ' de ' + value.empresa + ' (' + value.cif + ')';

return super._serializeValue(value);

window.customElements.define(UsoReflecttoattributeSerialize.is, UsoReflecttoattributeSerialize);

</script>

</dom-module>

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 13/11/2017
Disponible online en http://desarrolloweb.com/articulos/ejemplo-reflect-to-attribute-polymer2.html

Propiedades computed en Polymer 2

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 68 de 93
Manual de Polymer 2

Explicaciones sobre las propiedades computadas (computed) de Polymer 2 y ejemplos de


componentes donde se usan.

Las propiedades computadas son aquellas que toman su valor por medio de un cómputo, al que se llega
mediante los valores de otras propiedades del componente. Son especialmente útiles y se recurre a ellas en
gran cantidad de ocasiones.

Polymer 2, y su predecesor 1.x, hacen muy sencillo el trabajar con propiedades computadas. Además
realizan todo el trabajo pesado de manera automática, para que nosotros no tengamos que preocuparnos
porque los cómputos estén siempre correctamente actualizados. Para ello, cada vez que cambian los valores
de las propiedades usadas para realizar el cómputo, Polymer se encarga de actualizar el valor de las
propiedades computadas.

Se entenderán sin duda explicando casos de uso sencillos. Por ejemplo, podemos tener en un componente
dos propiedades: nombre y apellidos. Además podemos necesitar el "nombre completo" para otras cosas.
Esa propiedad nombre completo podría ser una propiedad computada, pues para obtener su valor se
consigue mediante la concatenación de las dos propiedades del elemento nombre y apellidos.

Otro ejemplo podría ser la letra del DNI. En España el número de identidad de las personas se acompaña a
una letra. Esa letra se puede calcular mediante unas operaciones a partir del número de identidad, por lo
tanto sería otro buen candidato a propiedad computada. Si tengo una factura y el total se calcula por medio
de la suma de todos los valores de cada concepto facturado, esa propiedad "total" podría ser una propiedad
computada. La fuerza de una clave, que se calcula en función de la cadena de la contraseña escrita por el
usuario, también podría ser una computada. Puedes encontrar interminables ejemplos.

Ejemplo de componente con propiedad computada

Vamos a realizar un primer ejemplo de un custom element en el que incluimos una propiedad computada.
Vamos a trabajar sobre el sencillo caso del "nombre completo" que es la contactenación del nombre y
apellidos. Verás que trabajar con computed properties en Polymer 2 es algo realmente fácil.

Como decimos, en nuestro componente tenemos tres propiedades:

nombre
apellidos
nombreCompleto, que es la computada a partir de las propiedades anteriores.

Para crear una propiedad computada tenemos que declararla como cualquier otra. Dentro de todas las
configuraciones que podemos realizar sobre las propiedades declaradas hay una llamada "computed". En

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 69 de 93
Manual de Polymer 2

ella debemos de colocar el nombre del método que se usará para realizar el cálculo, a fin de hallar el valor de
la propiedad. Además hay que señalar qué propiedad o propiedades se usan para para calcular el valor
resultante.

En esta declaración de propiedades encontramos la sintaxis utilizada para definir las computadas:

static get properties() {

return {

nombre: String,

apellidos: String,

nombreCompleto: {

type: String,

computed: 'definirNombreCompleto(nombre, apellidos)'

};

Como puedes ver, el método que se usará para realizar el cómputo es "definirNombreCompleto" y las
propiedades de las que se derivan el valor de la computada son "nombre" y "apellidos".

Esta declaración permite a Polymer 2 saber que, cada vez que cambien los valores de las propiedades
"nombre" y "apellidos", se tiene que invocar el método definirNombreCompleto().

Por supuesto, ese método lo tenemos que escribir dentro del componente. Recibirá exactamente los mismos
parámetros declarados en la propiedad computada y deberá devolver (return) el valor resultado del cálculo.

definirNombreCompleto(nombre, apellidos) {

return nombre + ' ' + apellidos;

Puedes ver a continuación el código del componente completo creado para este ejemplo.

<link rel="import" href="../../bower_components/polymer/polymer-element.html">

<dom-module id="avatar-usuario">

<template>

<style>

:host {

display: block

</style>

<div>

[[nombreCompleto]]

</div>

</template>

<script>

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 70 de 93
Manual de Polymer 2

class AvatarUsuario extends Polymer.Element {

static get is() {

return 'avatar-usuario';

static get properties() {

return {

nombre: String,

apellidos: String,

nombreCompleto: {

type: String,

computed: 'definirNombreCompleto(nombre, apellidos)'

};

constructor() {

super();

definirNombreCompleto(nombre, apellidos) {

return nombre + ' ' + apellidos;

window.customElements.define(AvatarUsuario.is, AvatarUsuario);

</script>

</dom-module>

Ejemplo fuerza de la clave con propiedad computada

Ahora veremos otro ejemplo de componente que tiene una propiedad computada, para calcular la fuerza de
una clave. Ya sabes, la fuerza depende de la clave escogida e indica al usuario que tan segura es una clave.

La declaración de nuestras propiedades ahora incluye la propia clave y su fuerza, siendo esta última una
computada.

static get properties() {

return {

clave: {

type: String,

value: ''

},

fuerza: {

type: Number,

value: 0,

computed: 'calcularFuerzaClave(clave)'

};

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 71 de 93
Manual de Polymer 2

El método que se usa para calcular la fuerza se llama calcularFuerzaClave() y recibe la clave por parámetro,
por tanto, cada vez que esa cadena "clave" cambie, se invocará al método que calcula la fuerza. Tendría un
código como el que sigue.

calcularFuerzaClave(clave) {

if(clave.length > 10) {

return 10;

return clave.length;

Como puedes apreciar, un método de una computada devuelve siempre un valor por medio de return, valor
que se cargará en la propiedad en cuestión cada vez que uno de sus parámetros cambie.

Nota: aquí el algoritmo que calcula la seguridad de la clave es indiferente. Obviamente el que hemos
escogido no es muy bueno, pero es lo de menos para el objetivo de este artículo.

El código completo de nuestro componente se puede ver a continuación:

<link rel="import" href="../../bower_components/polymer/polymer-element.html">

<dom-module id="fuerza-clave">

<template>

<style>

:host {

display: block

</style>

Clave: <input type="text" value="{{clave::input}}">

<div>

Fuerza: {{fuerza}}/10

</div>

</template>

<script>

class FuerzaClave extends Polymer.Element {

static get is() {

return 'fuerza-clave';

static get properties() {

return {

clave: {

type: String,

value: ''

},

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 72 de 93
Manual de Polymer 2

fuerza: {

type: Number,

value: 0,

computed: 'calcularFuerzaClave(clave)'

};

constructor() {

super();

calcularFuerzaClave(clave) {

if(clave.length > 10) {

return 10;

return clave.length;

window.customElements.define(FuerzaClave.is, FuerzaClave);

</script>

</dom-module>

Nota: en el código anterior observarás algo que probablemente te parecerá extraño: el binding del valor
de la clave escrito en un INPUT:

<input type="text" value="{{clave::input}}">

Esta sintaxis difiere de la que hemos explicado en el artículo de introducción al binding de Polymer 2 y
es necesaria cuando queremos hacer un doble binding sobre un elemento nativo del HTML y no un
elemento de Polymer. Hablaremos de este mecanismo de binding en otra ocasión.

Conclusión sobre las computed properties

En este artículo hemos podido conocer una de las herramientas más utilizadas en día a día del desarrollo de
componentes. Las propiedades computadas permiten reaccionar a cambios de una manera sencilla y
mantener actualizados los valores de los datos manejados internamente en el componente. Por medio de
una sintaxis sencilla podemos ejecutar funciones cuando ciertos valores cambian, ahorrando al desarrollador
la necesidad de suscribirse a eventos de cambio, lo que ahorra escribir código redundante al trabajar con
Polymer 2.

Hemos visto un par de ejemplos de componentes donde las propiedades computadas nos resultan de
utilidad, pero aplicaciones hay a montones y seguramente al desarrollar en poco tiempo encontrarás muchos
otros casos donde te resultan de utilidad.

Este artículo es obra de Miguel Angel Alvarez

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 73 de 93
Manual de Polymer 2

Fue publicado por primera vez en 27/11/2017


Disponible online en http://desarrolloweb.com/articulos/propiedades-computed-polymer2.html

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 74 de 93
Manual de Polymer 2

Observers en Polymer 2

Una de las herramientas más importantes para el desarrollo de componentes de Polymer son los observers.
Los observers nos permiten estar informados de los cambios en los datos que maneja el componente, ya
sean propiedades comunes, propiedades de objetos, subpropiedades, o secciones de un array. Existen
observers sencillos y observers complejos y los vamos a conocer todos en los próximos artículos. Además
también conoceremos cambios en los observers en la nueva versión de la librería, Polymer 2, pues han
incorporado nuevas funcionalidades, como la declaración de comodines en los observers, para observar
varias cosas a la vez sin necesidad de especificarlas.

Observers sencillos en Polymer 2


Qué son los observers y cómo declarar observers sencillos sobre propiedades individuales, con
ejemplos de desarrollo de componentes.

En este artículo del Manual de Polymer 2 vamos a conocer otra de las herramientas fundamentales para el
desarrollo con Polymer 2: los observers, o en español observadores. Básicamente los observers son
mecanismos mediante los cuales Polymer puede estar atento a los cambios sobre propiedades, de modo que
si éstas cambian, se pueda reaccionar ejecutando ciertas funciones. Son, con las propiedades computadas, las
herramientas más útiles para conseguir la programación reactiva, mediante la cual podemos escribir código
que sabemos se ejecutará cuando ciertos sucesos ocurran.

Los sucesos que detectan los observadores son esencialmente cambios, que pueden ocurrir sobre
propiedades simples, conjuntos de propiedades y en el caso de los arrays o de los objetos, de caminos
determinados. Con ellos conseguimos que Polymer esté pendiente de cambios que puedan surgir y ejecute
automáticamente las funciones que nosotros queramos cuando se detecten esos cambios.

Los observers más simples son los que vamos a ver en este artículo con ejemplos, los que ocurren sobre
propiedades simples.

Cómo definir un observer en una propiedad individual

A la hora de declarar una propiedad podemos configurar diversos comportamientos, que hemos descrito en
el artículo de Funcionalidades incorporadas en las propiedades de Polymer 2. Uno de ellos es justamente el
observer que se puede asociar a esa propiedad.

La sintaxis para definir un observer sobre una propiedad es la siguiente:

static get properties() {

return {

propiedad: {

type: String,

observer: 'funcionObservadora'

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 75 de 93
Manual de Polymer 2

},

};

El observer se configura indicando el nombre del método que se va a ejecutar cuando se detecten cambios
en la propiedad. La invocación será automática y correrá por cuenta de Polymer sin que tengamos que
intervenir.

El método observador recibirá como parámetro ciertos valores para facilitar el trabajo, que son básicamente
el valor actual de la propiedad y el valor que tenía justo antes del cambio detectado.

funcionObservadora(valorActual, valorAnterior) {

// Código del observer

Ya el código del observador permitirá ejecutar aquellas acciones necesarias ante los cambios y tendremos
disponibles esos valores, actual y anterior, recibidos por los parámetros, así como el acceso a cualquier otra
propiedad o método del componente que necesitemos acceder.

Ejemplo de observers en un componente que comprueba la validez de un email

Existen casos infinitos donde nos pueden venir muy bien los observers. Nosotros vamos a realizar uno
sencillo, en un componente que se encarga de comprobar la validez de un email.

Básicamente el componente se alimentará de un valor tipo cadena de email que se le entregará por medio de
un atributo en el componente y mostrará un icono cuando la cadena corresponda con un email
sintácticamente válido y otro cuando la cadena no sea un email valido.

Elementos para trabajar con iconos

Antes de comenzar tenemos que explicar que en este ejercicio nos hemos apoyado en componentes de
Polymer para trabajar con iconos que no hemos visto todavía. Estos componentes nos ofrecen una manera
muy cómoda de trabajar con iconos y una buena biblioteca con cientos de imágenes vectoriales muy útiles
en muchos tipos de aplicaciones.

Para trabajar con los iconos tendremos que instalar en nuestro proyecto dos nuevos elementos
personalizados de la biblioteca de Polymer. Lo hacemos de manera similar a lo que ya hemos contado en el
artículo de Instalar Polymer 2.

El primero de los componentes es el iron-icon, que es el que nos sirve para mostrar cualquier icono.

Lo instalas con el comando:

bower install --save PolymerElements/iron-icon

El segundo son las bibliotecas de iconos vectoriales que tienes en

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 76 de 93
Manual de Polymer 2

https://www.webcomponents.org/element/PolymerElements/iron-icons y que instalas con el comando:

bower install --save PolymerElements/iron-icons

Una vez instalados tenemos que asegurarnos de hace los correspondientes imports.

<link rel="import" href="../../bower_components/iron-icon/iron-icon.html">

<link rel="import" href="../../bower_components/iron-icons/iron-icons.html">

Y con ello ya podemos usar los iconos como por ejemplo:

<iron-icon icon="icons:check-circle">

Nota: iron-icons tiene como varias clasificaciones de iconos. La general la tienes en el import de iron-
icons.html, pero luego tienes por ejemplo hardware-icons.html o device-icons.html, etc. para obtener
iconos de otras clasificaciones.

Componente mostrar-validacion-email

Ahora vamos con la parte más relevante, la creación del componente. En este caso vamos a tener dos
propiedades, una es el email, que no inicializamos porque se supone que ese email nos lo pasarán vía
atributo al usar el componente. La otra propiedad es el icono que se debe mostrar, que cambia si el email es
válido o no.

La propiedad donde colocaremos el observador es la del email, de modo que cada vez que cambia se ejecute
un método como respuesta.

static get properties() {

return {

email: {

type: String,

observer: 'comprobarEmail'

},

icono: {

type: String,

value: "icons:clear"

};

Ahora podemos ver el método configurado como observer.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 77 de 93
Manual de Polymer 2

comprobarEmail(email) {

if(this.validateEmail(email)) {

this.icono = 'icons:check';

} else {

this.icono = 'icons:clear';

Este método recibe el email, que es el nuevo email, con el valor al que acaba de cambiar. En el método se
hacen las comprobaciones oportunas y con ellas se edita el icono que se debe mostrar para representar si el
email era o no correcto.

Nota: si te acuerdas de las propiedades computed, quizás te des cuenta que este ejercicio se podría
haber resuelto también con ellas como alternativa, haciendo la propiedad del icono como computada.
Son dos vías para resolver un mismo problema, algunas veces será más cómodo trabajar con
observadores y otra te resultará más adecuado trabajar con computadas. Los dos son programación
reactiva y resultan muy útiles de usar.

Podemos ver el código del componente completo para salir de posibles dudas de implementación.

<link rel="import" href="../../bower_components/polymer/polymer-element.html">

<link rel="import" href="../../bower_components/iron-icon/iron-icon.html">

<link rel="import" href="../../bower_components/iron-icons/iron-icons.html">

<dom-module id="marcar-email-valido">

<template>

<style>

:host {

display: inline;

</style>

<iron-icon icon="[[icono]]">

</template>

<script>

class MarcarEmailValido extends Polymer.Element {

static get is() {

return 'marcar-email-valido';

static get properties() {

return {

email: {

type: String,

observer: 'comprobarEmail'

},

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 78 de 93
Manual de Polymer 2

icono: {

type: String,

value: "icons:clear"

};

constructor() {

super();

comprobarEmail(email,e2, e3) {

if(this.validateEmail(email)) {

this.icono = 'icons:check';

} else {

this.icono = 'icons:clear';

validateEmail(email) {

var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-

Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

return re.test(email);

window.customElements.define(MarcarEmailValido.is, MarcarEmailValido);

</script>

</dom-module>

Nota: la función de validación del email la he sacado de stackoverflow.

Dependencias del observer

Llamamos las dependencias del observador a aquellas propiedades que son observadas, provocando la
invocación de los métodos observadores cuando sus valores cambian.

En los observadores sencillos solo se declara una única dependencia, la propiedad única que está siendo
observada. Si quieres observar más de una propiedad al mismo tiempo, entonces debes trabajar con
observadores complejos, de los cuales vamos a hablar en los próximos artículos.

No obstante, cabe aclarar ya, a modo de recomendación, que en el código de los métodos observadores no
es buena idea confiar en propiedades del componente que no formen parte de las dependencias del
observador.

Por ejemplo, mira esta declaración de propiedades:

static get properties() {

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 79 de 93
Manual de Polymer 2

return {

valorSinImpuestos: {

type: Number,

observer: 'valorCambiado'

},

tipoIVA: {

type: Number

Ahora mira este observer, que no sería muy recomendable de implementar:

// Ojo!! cuidado con este código, pues es un ANTIPATRÓN

valorCambiado(nuevoValor, valorAnterior) {

var valorConImpuestos = nuevoValor + (nuevoValor * this.tipoIVA) / 100;

El problema con el método anterior, motivo por el cual se considera un antipatrón, es que, si cambia la
propiedad "tipoIVA", el método observador no se invocará, pues "tipoIVA" no pertenece como
dependencias a este observador. Además, Polymer no nos asegura el orden con el que se inicializan las
propiedades, por lo que podría ocurrir que, al ejecutarse este método observador, el valor de "tipoIVA" sea
"undefined".

Lo correcto sería tener un observer complejo, en el que podamos acompañar dos propiedades a la vez. Esto
lo veremos más adelante.

De momento es todo. Insistimos que solo hemos hablado de los observadores más sencillos. Más adelante
explicaremos a trabajar con casos otra manera de declarar los observers, más compleja y versátil, también
muy usada en Polymer y Polymer 2.

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 12/12/2017
Disponible online en http://desarrolloweb.com/articulos/observers-sencillos-polymer-2.html

Observers complejos, de dos o más propiedades, en Polymer 2


Introducción de los observers complejos en Polymer, declarados en la propiedad observers, que
nos permiten observar de una sola vez valores en dos o más propiedades.

En el artículo anterior del Manual de Polymer 2 estudiamos los observers simples en Polymer 2, que nos
permiten observar los cambios en una propiedad. Pero en la práctica no siempre es suficiente este tipo de
observadores, puesto que muchos procesos dependen de más de una propiedad al mismo tiempo.

Para casos más avanzados en Polymer (tanto en la versión 1.x como en la 2.x) existen los observadores
complejos, que nos permiten declararlos de una manera diferente y más versátil, que vamos a estudiar en el

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 80 de 93
Manual de Polymer 2

presente texto. Aunque ya vienen existiendo en Polymer 1.x, los observers complejos han sufrido cambios
interesantes que tendrán que aprender también los que ya conocían esta librería.

Declaración observers

Los observers complejos en Polymer requieren una declaración específica, independiente de la declaración
de propiedades. Esta declaración de observers complejos permite definir de manera centralizada todos los
observers utilizados en un componente, pero además habilita diversas posibilidades adicionales para los
métodos observadores.

Esta declaración es mucho más versátil, permitiendo observar cambios en una propiedad, pero también en
un conjunto de propiedades, en atributos profundos de un objeto o en las casillas de elementos de un array.
De manera similar a otras declaraciones en clases de componentes de Polymer 2, para la especificación de
los observers complejos usaremos también una propiedad estática, definida por un getter de la clase del
componente. No debería representar ningún problema, pues es algo que has hecho ya múltiples veces para
la definición de propiedades.

En este artículo vamos a conocer la sintaxis esencial de la declaración de observers, realizando ejemplos de
observar dos o más propiedades a la vez. En futuras entregas veremos otros ejemplos que nos permitirán
observar arrays o bien atributos internos de los objetos, a cualquier profundidad, por medio de caminos
(paths).

Los observers se indican por mediación de un array, en el que se declaran mediante una cadena todos los
métodos observadores y sus propiedades, un observer por posición del array.

static get observers() {

return [

observer1(propiedad1, propiedad2)',

observer2(propiedad3, propiedad4, propiedad5)',

observerX(propiedadX)

En este caso hemos definido 3 observers, en los que se controla el valor de distintos juegos de propiedades.
Puedes observar al mismo tiempo cualquier número de propiedades del componente:

Nota: Incluso puedes observar una única propiedad, como en el método "observerX" (aunque en este

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 81 de 93
Manual de Polymer 2

caso también podrías usar observers simples, siempre que esa propiedad no sea un array del que
queremos controlar sus ítem o una propiedad profunda de un objeto).

Para cada observador se declara el conjunto de propiedades que se están vigilando, por medio de los
parámetros del método observador. Luego se tienen que declarar los métodos que hacen la función de
observadores, por ejemplo:

observer1(propiedad1, propiedad2) {

//código del observador

Estos métodos se invocarán automáticamente cada vez que cambie una de las propiedades observadas.
Como te puedes imaginar, en el método observador recibimos los valores actuales de las propiedades. No
solo las propiedades que acaban de cambiar, sino el conjunto de propiedades observadas.

Ejemplo de uso de observers complejos

En el siguiente ejemplo podemos ver un componente en el que declaramos un observer complejo, por
medio de la declaración "observers". Nuestro ejemplo servirá para ilustrar el caso de vigilar el valor de dos
propiedades al mismo tiempo.

El componente es un supuesto elemento que nos ofrece un dato sobre la "probabilidad de lluvia". Para
calcular la probabilidad de lluvia hemos supuesto que necesitamos dos valores: la humedad y la presión
atmosférica. Como esa probabilidad cambia cuando cualquiera de esos dos valores se altere, tenemos que
usar la declaración de observers necesariamente.

Nota: No me he dedicado a estudiar meteorología, por lo que mis suposiciones para calcular la
probabilidad de lluvia son solo fruto de mi propia imaginación. En definitiva, nos da igual cómo se
calcule la probabilidad de lluvia, lo que nos interesa es ver un observer de dos propiedades a la vez.

La interfaz de mi componente se puede ver en la siguiente imagen:

Existen unos controles para cambiar los valores de presión atmosférica y de humedad, para que se pueda
comprobar que, cada vez que cambian, se invoca el método observador.

La declaración de la propiedad observers, con el array de métodos observadores, es la siguiente:

static get observers() {

return [

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 82 de 93
Manual de Polymer 2

'calcularProbabilidad(presionAtmosferica, humedad)'

Ahora veamos el método observador:

calcularProbabilidad(presionAtmosferica, humedad) {

console.log('Estoy en CalcularProbabilidad', presionAtmosferica, humedad);

if(presionAtmosferica < 1 || humedad < 30) {

this.probabilidadLluvia = 'Baja';

} else if(presionAtmosferica < 2 || humedad < 50) {

this.probabilidadLluvia = 'Media';

} else if(presionAtmosferica < 3 || humedad < 70) {

this.probabilidadLluvia = 'Alta';

} else {

this.probabilidadLluvia = 'Muy alta';

El algoritmo usado es indiferente. Lo que tienes que ver es que el observador recibe los dos valores
observados y se usan dentro del método para calcular el dato que necesitábamos. Obviamente, dentro de
este método podríamos acceder a cualquier otra propiedad del componente, para obtener los valores
actuales o alterarlos.

El código completo del componente lo puedes ver a continuación.

<link rel="import" href="../../bower_components/polymer/polymer-element.html">

<dom-module id="probabilidad-lluvia">

<template>

<style>

:host {

display: flex;

align-items: center;

font-family: sans-serif;

font-size: 0.9em;

border: 1px solid #ddd;

padding: 10px;

justify-content: space-around;

span {

font-weight: bold;

display: block;

div {

text-align: center;

margin: 10px;

.probabilidad {

color: #003399;

font-size: 1.2em;

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 83 de 93
Manual de Polymer 2

h2 {

font-size: 1.1em;

margin: 0 0 10px 0;

</style>

<div>

<span>Presión atmosférica</span>

[[presionAtmosferica]]

<footer>

<button on-click="aumentarPresion">+</button>

<button on-click="disminuirPresion">-</button>

</footer>

</div>

<div>

<span>Humedad</span>

[[humedad]]%

<footer>

<button on-click="aumentarHumedad">+</button>

<button on-click="disminuirHumedad">-</button>

</footer>

</div>

<div class="probabilidad">

<h2>Probabilidad de lluvia</h2>

[[probabilidadLluvia]]

</div>

</template>

<script>

class ProbabilidadLluvia extends Polymer.Element {

static get is() {

return 'probabilidad-lluvia';

static get properties() {

return {

presionAtmosferica: Number,

humedad: Number,

probabilidadLluvia: String

};

static get observers() {

return [

'calcularProbabilidad(presionAtmosferica, humedad)'

constructor() {

super();

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 84 de 93
Manual de Polymer 2

calcularProbabilidad(presionAtmosferica, humedad) {

console.log('Estoy en CalcularProbabilidad', presionAtmosferica, humedad);

if(presionAtmosferica < 1 || humedad < 30) {

this.probabilidadLluvia = 'Baja';

} else if(presionAtmosferica < 2 || humedad < 50) {

this.probabilidadLluvia = 'Media';

} else if(presionAtmosferica < 3 || humedad < 70) {

this.probabilidadLluvia = 'Alta';

} else {

this.probabilidadLluvia = 'Muy alta';

aumentarPresion() {

this.presionAtmosferica++;

aumentarHumedad() {

this.humedad += 10;

disminuirPresion() {

this.presionAtmosferica--;

disminuirHumedad() {

this.humedad -= 10;

window.customElements.define(ProbabilidadLluvia.is, ProbabilidadLluvia);

</script>

</dom-module>

Como práctica te sugerimos comprobar qué pasa a la hora de usar este componente, si hacemos algo como
esto:

<probabilidad-lluvia presion-atmosferica="2.9" humedad="50"></probabilidad-lluvia>

Verás que, nada más inicializarse el componente, se llamará al método observador, con los valores de las
propiedades definidas.

Si por contra, no se definieran todas las propiedades, pero al menos una de ellas sí:

<probabilidad-lluvia presion-atmosferica="1.5"></probabilidad-lluvia>

Se invocaría también al método observador, con el valor definido en una propiedad y el valor "undefined"
en la otra.

Obtener el valor anterior de las propiedades

Una limitación de los observers complejos, en relación a los observers simples sobre una única propiedad,

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 85 de 93
Manual de Polymer 2

es que somos incapaces de recibir los valores anteriores de las propiedades.

Recuerda que en los observers simples, que se vigilaba únicamente una propiedad, recibimos como
parámetro tanto el valor actual de la propiedad como el valor anterior. Esto es algo que no permiten los
observers complejos, pues no hay manera de que nos provean de ese valor anterior.

Si estás haciendo un componente y para un caso concreto necesitas los valores actual y anterior de una
propiedad, la única solución automática sería apoyarse en observers simples.

Nota: Si necesitas observar dos propiedades al mismo tiempo y además conseguir sus valores
anteriores, el problema de usar observers sencillos serían las dependencias del observador. Pues
realmente solo estarías observando una propiedad y no dos al mismo tiempo. Recuerda que, por norma,
en los métodos de los observers deberíamos limitarnos a confiar solamente en las propiedades
observadas y no otras propiedades del componente. Por tanto, en un observador sencillo, necesario para
ser capaces de acceder al valor anterior, no deberíamos consultar otras propiedades. En el caso que lo
hagas deberías tener en cuenta:

Las propiedades que no sean dependencias podrían no estar inicializadas


Podría darse el caso que cambien las propiedades que no son dependencias y que el
observador no se invoque, porque solo se invocará si cambian sus dependencias.

Conclusión sobre los observers complejos a varias propiedades

Ahora ya sabes implementar observers complejos. Este conocimiento te servirá para innumerables
situaciones y junto con los observers simples que conociste en el artículo anterior ya tienes una buena
cantidad de información sobre cómo funcionan los observaores de Polymer 2, una de las fundamentales
herramientas que nos proporcionan para la implementación de componentes.

Sin embargo, aún nos queda por aprender algunos otros usos también bastante utilizados en observers,
como observar modificaciones de casillas de arrays y de propiedades profundas de objetos. En este apartado
Polymer 2 ofrece algunas importantes novedades, pero esto ya es un tema que dejamos para los próximos
capítulos del Manual de Polymer 2.

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 28/12/2017
Disponible online en http://desarrolloweb.com/articulos/observers-complejos-propiedades-polymer2.html

Observers de propiedades profundas de objetos en Polymer 2


Aprende a crear observers complejos, en el que se observa el estado de propiedades de objetos, con
caminos profundos.

En el Manual de Polymer 2 hemos dedicado ya dos capítulos a los observers, pero aún no hemos terminado
de contarte todo. En el capítulo anterior vimos los observadores complejos de Polymer 2 y comprobamos
que mediante su declaración podemos vigilar el cambio en dos propiedades al mismo tiempo. En este
artículo debemos continuar hablando de ellos, pues hay detalles que no hemos explicado todavía y que

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 86 de 93
Manual de Polymer 2

necesitarás saber para no volverte loco al usarlos en tus propios componentes.

Veremos cómo acompañar el estado en las propiedades profundas de los objetos y cómo permitir que
Polymer 2 ejecute los mecanismos de binding, y los observers, cuando se modifican mediante la asignación
de nuevos valores en el código de los métodos del componente.

Qué son propiedades profundas y cuáles son sus características

Comencemos con una aclaración sobre las propiedades profundas de objetos (deep properties). Nosotros
podemos tener un objeto dentro de una propiedad de Polymer y ese objeto puede tener varias propiedades
profundas.

Por ejemplo, el objeto "contacto" puede tener propiedades profundas como "contacto.nombre" y
"contacto.email". El objeto "contacto" podría ser la propiedad de un componente y para distinguir a las
propiedades del objeto "nombre" o "email" las llamamos propiedades profundas.

El caso es que las propiedades profundas en Polymer, y esto es algo que ocurre tanto en 1.x como en 2.x,
tienen unos tratamientos especiales, para aumentar el rendimiento del framework, que son los que vamos a
explicar en este artículo.

Lo primero que debes saber es que, cuando realizamos un observador de un objeto, ese observador sólo se
ejecutará cuando todo el objeto cambie y no cuando cambie una de sus propiedades.

Por ejemplo, si tengo un observer declarado sobre la propiedad contacto:

static get properties() {

return {

contacto: {

type: Object,

observer: 'vigilarContacto'

Aunque en algún momento cambien sus propiedades profundas (contacto.nombre, o contacto.email), no se


ejecutará el observer "vigilarContacto". Eso es porque ese observador se ha declarado sobre el objeto en sí,
el objeto completo y no sobre sus propiedades profundas.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 87 de 93
Manual de Polymer 2

Nota: Por si te lo preguntas, para que se ejecutase el observer vigilarContacto tendría que ocurrir que se
le asignase otro objeto a esa propiedad. Por ejemplo con this.contacto = new('Miguel',
'miguel@desarrolloweb.com'); Al crearse ese nuevo objeto y asignarse a la propiedad contacto, como el
objeto creado es totalmente nuevo, sí se se ejecutaría el método vigilarContacto. Sin embargo eso es algo
que generalmente no se desea, pues lo más normal es que el objeto siga siendo siempre el mismo y lo
que se altere en el uso del componente son sus propieades profundas.

Aunque usásemos observers complejos, si observamos el propio objeto, no estamos observando sus deep
properties.

static get observers() {

return [

'observarObjeto(contacto)'

Esa era la sintaxis de los observers complejos, pero si lo que estamos observando es el objeto, no ocurriría
nada aunque cambiasen sus propiedades profundas.

Observar propiedades profundas

Ahora que ha quedado claro que observar un objeto no funciona si lo que queremos es observar sus deep
properties, vamos a aprender qué se puede hacer.

Para comenzar, debes saber que las propiedades profundas solo se pueden observar desde observers
compejos. En ellos debemos declarar qué propiedades profundas del objeto se desean observar, indicando
el camino por medio del operador "punto".

Esta es la sintaxis de la declaración observers en Polymer 2 en la que estaríamos observando propiedades


profundas:

static get observers() {

return [

'comprobarNombre(contacto.nombre)',

'comprobarVariosValores(contacto.nombre, contacto.email)'

En la declaración anterior tienes dos ejemplos de observadores declarados, en el primero se vigila una
propiedad profunda única y en el segundo dos propiedades profundas al mismo tiempo.

Ya solamente te quedaría escribir el código de tus métodos observadores. Pero eso lo vamos a ver luego con
un ejemplo completo de componente.

Asegurarse que se ejecutan los observadores y mecanismos de binding

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 88 de 93
Manual de Polymer 2

Cuando se modifican propiedades profundas de los objetos Polymer 2 no siempre ejecuta los mecanismos
de binding y los observers declarados. Vamos a aprender ahora a asegurarnos que todo vaya correctamente
cuando nosotros alteramos las propiedades profundas en el código de los métodos del componente.

Nota: Esto lo hace Polymer por motivos de rendimiento, pues sería muy costoso escalar eventos ante la
modificación de cualquier propiedad profunda, ante cualquier situación en la que ésta pueda alterarse.
Ten en cuenta que un objeto puede tener decenas de propiedades y no todas te interesa que se estén
controlando mediante binding o observers, por lo que Polymer 2 obvia cualquier cambio en las
propiedades profundas a no ser que realmente se necesite.

Por ejemplo, vamos a continuar con nuestro ejemplo del objecto "contacto" y las propiedades profundas
"nombre" y "email". Si nosotros hacemos algo como esto:

metodoDelComponente() {

this.contacto.nombre = 'Miguel Angel Alvarez';

this.contacto.email = 'miguel@escuela.it';

Al ejecutarse el metodoDelComponente(), a pesar que yo edito las propiedades profundas, asignando


nuevos valores, esto no desencadena el binding o los observers.

No se ejecutaría el binding

Quiere decir que si yo en mi template tengo un binding como:

<div>

Nombre: {{contacto.nombre}}

</div>

No se modificaría el template aunque hubiera asignado un nuevo valor a contacto.nombre con


this.contacto.nombre = 'nuevo valor'.

No se ejecutarían los observers

Si yo tengo un observer declarado así:

static get observers() {

return [

'comprobarNombre(contacto.nombre)'

Tampoco se ejecutaría si se ejecuta algo como this.contacto.nombre = 'nuevo valor'.

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 89 de 93
Manual de Polymer 2

Método set() para ejecutar binding y observers

El método set(), que forma parte de cualquier componente de Polymer 2, es el que nosotros debemos usar
cuando se modifican propiedades profundas de los objetos. Es el que nos asegura que los mecanismos de
binding y los observers se ejecuten como se desea.

Para usar set() simplemente debemos indicar la cadena con el camino a la propiedad profunda que
queremos actualizar.

metodoDelComponente() {

this.set('contacto.nombre', 'Miguel Angel Alvarez');

Una vez asignado un nuevo valor a contacto.nombre por medio de set(), comprobarás que los observadores
y los mecanismos de binding sí se ejecutan.

Ejemplo completo de componente para practicar con observers sobre propiedades


profundas

Ahora vamos a ver un componente que nos sirva de ejemplo para todo lo aprendido. En este componente
tenemos una interfaz para colocar una clave, que tiene dos campos de texto, uno para colocar la clave y otro
para repetirla (y así estar seguros que, siendo ambas claves iguales, la clave está bien escrita).

En nuestro componente tendremos la clave, y su repetición, declarada con un objeto, que tiene dos
propiedades profundas.

static get properties() {

return {

clave: {

type: Object,

value: function() {

return {

value: '',

repeticion: ''

};

Nota: es relevante que indiques una inicialización para los valores de la clave, a la hora de usar esos
valores en campos de texto, aunque simplemente los campos desees que aparezcan vacíos. Los estamos
inicializando mediante una función, algo que es necesario en Polymer.

Podemos definir dos observadores en este componente:

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 90 de 93
Manual de Polymer 2

Uno para comprobar la clave y ver si está bien escrita, es segura y todo lo que necesites saber.
Otro para comprobar si las dos claves son iguales.

static get observers() {

return [

'comprobarClave(clave.value)',

'comprobarIguales(clave.value, clave.repeticion)'

Ahora podemos ver los ejemplos de implementación de estos observadores, en los que se realizan tareas
básicas.

comprobarClave(cadena) {

if(cadena == '') {

this.errorClave = '* Campo requerido';

} else {

this.errorClave = '';

comprobarIguales(value, repeticion) {

if(value != repeticion) {

this.errorRepeticion = '* Las claves no son iguales';

} else {

this.errorRepeticion = '';

Ahora imaginemos que tenemos un método que debe realizar un reseteo de los campos clave y la repetición
de la clave. Para ese reseteo debemos asignar nuevos valores a las propiedades profundas. Veamos este
código primero, aunque de momento esta alternativa "va con trampa" para reforzar algo sobre lo que ya
hemos hablado antes.

reset() {

this.clave.value = '';

this.clave.repeticion = '';

¿Ese código de reset() funcionaría? Obviamente no, porque al modificar propiedades profundas debemos
usar set(), pues en caso contrario no se ejecutarían los observers ni los mecanismos de binding.

Esta otra alternativa sería la correcta para nuestro método reset().

reset() {

this.set('clave.value', '');

this.set('clave.repeticion', '');

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 91 de 93
Manual de Polymer 2

Podemos ver el código completo del componente que hemos construido para ilustrar este artículo.

<link rel="import" href="../../bower_components/polymer/polymer-element.html">

<link rel="import" href="../../bower_components/paper-input/paper-input.html">

<dom-module id="claves-iguales">

<template>

<style>

:host {

display: block;

border: 1px solid #ddd;

padding: 10px;

div {

display: flex;

align-items: center;

span {

color: red;

font-size: 0.9em;

margin: 10px 0 0 20px;

paper-input {

width: 50%;

</style>

<div>

<paper-input label="clave" value="{{clave.value}}"></paper-input>

<span>[[errorClave]]</span>

</div>

<div>

<paper-input label="Repetir clave" value="{{clave.repeticion}}"></paper-input>

<span>[[errorRepeticion]]</span>

</div>

<button on-click="reset">Resetear</button>

</template>

<script>

class ClavesIguales extends Polymer.Element {

static get is() {

return 'claves-iguales';

static get properties() {

return {

errorClave: String,

errorRepeticion: String,

clave: {

type: Object,

value: function() {

return {

value: '',

repeticion: ''

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 92 de 93
Manual de Polymer 2

};

static get observers() {

return [

'comprobarClave(clave.value)',

'comprobarIguales(clave.value, clave.repeticion)'

constructor() {

super();

comprobarClave(cadena) {

if(cadena == '') {

this.errorClave = '* Campo requerido';

} else {

this.errorClave = '';

comprobarIguales(value, repeticion) {

console.log('comprobarIguales', value, repeticion);

if(value != repeticion) {

this.errorRepeticion = '* Las claves no son iguales';

} else {

this.errorRepeticion = '';

reset() {

// this.clave.value = '';

// this.clave.repeticion = '';

this.set('clave.value', '');

this.set('clave.repeticion', '');

window.customElements.define(ClavesIguales.is, ClavesIguales);

</script>

</dom-module>

Con esto ya hemos avanzado mucho en el campo de los observers, pero aún nos queda por aprender otros
casos importantes, como son la posibilidad de observar cambios en cualquier propiedad profunda, por
medio de un comodín, así como la realización de observadores en elementos de arrays. Más adelante lo
abordaremos.

Este artículo es obra de Miguel Angel Alvarez


Fue publicado por primera vez en 19/01/2018
Disponible online en http://desarrolloweb.com/articulos/observers-propiedades-profundas-objetos-polymer.html

http://desarrolloweb.com/manuales/manual-polymer-2.html Página 93 de 93

Das könnte Ihnen auch gefallen