> Manuales > Manual 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 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.

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.

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

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>

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.

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.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual