Tabla de contenido

Librerias a importar

<base href="https://cdn.rawgit.com/download/polymer-cdn/2.6.0/lib/">
<script src="webcomponentsjs/webcomponents-loader.js"></script>

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

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

Estructura básica de un componente

Un componente de Polmer está constituido por tres partes

  • Template: tag html que describe el la vista del componente.
  • Style: apartado donde se escriben los estilos
  • Script: definición del componente
<dom-module id="polymer-element">
 <template>
   <style>
     :host h1{
       background-color: blue;
       color : white;
     }
     :host h1 span{
       color: cyan;
     }
   </style>
   <h1>The current month is <span>[[month]]</span> !!</h1>
 </template>
  <script>
   class PolymerElement extends Polymer.Element {
     static get is() { return "polymer-element"; }
     static get properties() {
       return {
         month: {
           type: String,
           value:'Janary'
         }
       };
     }
   }
   customElements.define(PolymerElement.is, PolymerElement);
 </script>
</dom-module>

Data binding

Es la forma en que se vinculan los datos entre el javascript y el Template HTML y va en dos formas

One-way data binding

Cuando queremos mostrar el valor de una propiedad dentro del HTML se hace un simple binding y esto de hace encerrando entre corchetes en nombre de la propiedad <span>[[month]]</span>

<dom-module id="polymer-element">
 <template>
   <style>
     :host h1{
       background-color: blue;
       color : white;
     }
     :host h1 span{
       color: cyan;
     }
   </style>
   <h1>The current month is <span>[[month]]</span> !!</h1>
 </template>
 <script>
   class PolymerElement extends Polymer.Element {
     static get is() { return "polymer-element"; }
     static get properties() {
       return {
         month: {
           type: String,
           value:'Janary'
         }
       };
     }
   }
   customElements.define(PolymerElement.is, PolymerElement);
 </script>
</dom-module>

Two-way data binding

Cuando necesitamos mostrar y tener la capacidad de modificar el valor de una propiedad dentro del HTML utilizamos el double binding que es encerrar entre llaves el nombre de la propiedad .de esta forma lo que se escriba en el input afectará a la propiedad.

<dom-module id="polymer-element">
 <template>
   <style>
     :host h2{
       background-color: blue;
       color : white;
     }
     :host h2 span{
       color: cyan;
     }
   </style>
   <h1>Two-way data binding</h1>
   <h2>The current month is <span>[[month]]</span> !!</h2>
   Change value <input type="text" value=" { { month::input } }  "></input>
 </template>
  <script>
   class PolymerElement extends Polymer.Element {
     static get is() { return "polymer-element"; }
     static get properties() {
       return {
         month: {
           type: String,
           value:'Janary'
         }
       };
     }
   }
   customElements.define(PolymerElement.is, PolymerElement);
 </script>

</dom-module>

Data binding a un atributo

En ocasiones es necesario cambiar el valor de un atributo de un elemento HTML con el valor de una propiedad para eso el data binding se usa anteponiendo el signo $ antes del signo igual <h2 class$="[[customColor]]"> donde customColor es una propiedad del componente

<dom-module id="polymer-element">
 <template>
   <style>
     :host h2{
       background-color: blue;
       color : white;
     }
     :host h2 span{
       color: cyan;
     }
     :host .orange{
       background-color: #FF9A06;
     }
   </style>
   <h1>Two-way data binding</h1>
   <h2 class$="[[customColor]]">The current month is <span>[[month]]</span> !!</h2>
   Change value <input type="text" value=""></input>
 </template>
  <script>
   class PolymerElement extends Polymer.Element {
     static get is() { return "polymer-element"; }
     static get properties() {
       return {
         month: {
           type: String,
           value:'Janary'
         },
         customColor:{
           type: String,
           value: 'orange'
         }
       };
     }
   }
   customElements.define(PolymerElement.is, PolymerElement);
 </script>
</dom-module>

Estructura dom-repeat

En ocasiones es necesario utilizar ciclos para generar elementos para eso es necesario utilizar la estructura dom-repeate. En el ejemplo se muestra la forma de iterar un array que contiene los meses del año, para empezar se tiene una propiedad llamada months

  months:{
           type: Array,
           value:[
             {month:1,season:'Winter',value:'January'},
             {month:2,season:'Winter',value:'February'},
             {month:3,season:'Spring',value:'March'},
             {month:4,season:'Spring',value:'April'},
             {month:5,season:'Spring',value:'May'},
             {month:6,season:'Summer',value:'June'},
             {month:7,season:'Summer',value:'July'},
             {month:8,season:'Summer',value:'August'},
             {month:9,season:'Fall',value:'September'},
             {month:10,season:'Fall',value:'October'},
             {month:11,season:'Fall',value:'November'},
             {month:12,season:'Winter',value:'December'}
           ]
         }

y en el template del componente generamos tantos botones como meses definidos.

<template is="dom-repeat" items="[[months]]">
  <div>
    <button>[[item.value]]</button>
  </div>
</template>

Estructura dom-if

Para ocupar la estructura condicional if necesitamos <template is="dom-if" if="{ {spring} }" > dónde spring es la expresión a evaluar. En el ejemplo siguiente tenemos cuatro variables que corresponden a las estaciones del año de tipo Booleano y solo se encuentra una activa.

spring:{
 type: Boolean,
 value: false
},
summer:{
 type: Boolean,
 value: true
},
fall:{
 type: Boolean,
 value: false
},
winter:{
 type: Boolean,
 value: false
}

De esta forma podemos crear una estructura dentro del template principal de nuestro elemento para evaluar esta variable para que se muestre solo la estación actual

<template is="dom-if" if="{ {spring} }" >
 <h3>Spring</h3>
</template>
<template is="dom-if" if="{ {summer} }" >
 <h3>Summer</h3>
</template>
<template is="dom-if" if="{ {fall} }" >
 <h3>Fall</h3>
</template>
<template is="dom-if" if="" >
 <h3>Winter</h3>
</template>

Métodos

Los métodos son declarados dentro de la clase

class PolymerElement extends Polymer.Element {
 static get is() { return "polymer-element"; }
 static get properties() {...}
 changeSeason(){
   //--TODO
 }
}
customElements.define(PolymerElement.is, PolymerElement);

Eventos

los eventos se establecen en dos fases, dentro del template <button on-click = "selectMonth" ></button> y su definición dentro de la clase del componente selectMonth(event){ //--TODO } .

<template>
 ...
 <button on-click="selectMonth" >[[item.value]]</button>
 ...
</template>

class PolymerElement extends Polymer.Element {
 static get is() { return "polymer-element"; }
 static get properties() {...}
  selectMonth(event){
   //--TODO
   //--event.model.item
 }
}
customElements.define(PolymerElement.is, PolymerElement);

Arrays

Los array son tipo de dato especial al momento de asignar valores es por eso que es necesario acceder, obtener y agregar valores a través de los métodos siguientes, ya que si no lo hacemos a través de estos métodos no se disparan los observables

Get

Obtener un valor de un array donde 5 es la posición del array

this.get('months.5.season')

Set

Actualizar un valor dentro de un array donde 5 es la posición a actualizar.

this.set('months.5.season','none')

Push

Utilizada para agregar un valor, este lo agregara al final

this.push('months',{month:12,season:'Winter',value:'December'})

Splice

Cuando queremos eliminar un valor donde 1 es la posición inicial y 2 es el número de elementos a eliminar

this.splice('months',1,2)

Anidar componentes

Para anidar componentes necesitamos definir dos componentes para este caso.

<dom-module id="polymer-element-one">
<dom-module id="polymer-element-two">

Dentro del template de PolymerElementOne agregamos la línea siguiente para insertar el segundo componente.

<polymer-element-two></polymer-element-two> 
<polymer-element-one></polymer-element-one>

<dom-module id="polymer-element-one">
<template>
  <style>
    :host {
      background-color: blue;
      display: block;
      padding: 4px;
    }
  </style>
  <h1>I am a component !!</h1>
<polymer-element-two></polymer-element-two> 
</template>
 <script>
  class PolymerElementOne extends Polymer.Element {
    static get is() { return "polymer-element-one"; }
    static get properties() {
      return {};
    }
  }
  customElements.define(PolymerElementOne.is, PolymerElementOne);
</script>
</dom-module>

<dom-module id="polymer-element-two">
<template>
     <style>
    :host {
      background-color: green;
      display: block;
      padding: 4px;
    }
  </style>
  <h2> I am a second componente  !!</h2>
</template>
 <script>
   class PolymerElementTwo extends Polymer.Element {
     static get is() { return "polymer-element-two"; }
     static get properties() {
       return {     }
     }
  }
  customElements.define(PolymerElementTwo.is, PolymerElementTwo);
</script>
</dom-module> 

Como pasar propiedades entre componentes

Para pasar valores entre componentes es necesario enviarlos vía parámetros de esta forma para el ejemplo anterior para pasar el valor de la propiedad name del componente <polymer-element-one> al componente <polymer-element-two> es necesario cambiarlo de la forma <polymer-element-two name=""></polymer-element-two>

Notify

Cuando se comparten valores entre componentes es necesario activar la propiedad notify para poder escuchar los cambios, de esta forma en el último ejercicio si se modifica la propiedad name en el componente <polymer-element-two> es necesario agregar la propiedad notify para que los cambios puedan ser escuchadas en el componente <polymer-element-one> de la forma name:{type:String, notify:true }

Observer

En ocasiones es necesario observar una variable para aplicar una acción para eso son los observables; de esta forma en el último ejemplo si cuando cambia la variable name podríamos agregar un observable en dos pasos.

1- Declarar la propiedad observer dentro de la definición de una propiedad y asignarle qué método se disparará cuando la variable cambie

name:{ type:String,observer:"changedName"}
  1. La segunda es agregar el método, este define dos valores el actual y el anterior
    changedName(new_value, old_value ){
      console.info(`Old value:[${old_value}] New Value:[${new_value}]`)
    }
    
<polymer-element-one></polymer-element-one>

<dom-module id="polymer-element-one">
<template>
  <style>
    :host {
      background-color: cyan;
      display: block;
      padding: 4px;
    }
  </style>
  <h1>I am a component !!</h1>
  <input type="text" value="" >
  <h2> Make by [[name]]</h2>
  <polymer-element-two parent-name="" ></polymer-element-two> 
  
  <polymer-element-two parent-name="" ></polymer-element-two> 

</template>
 <script>
  class PolymerElementOne extends Polymer.Element {
    static get is() { return "polymer-element-one"; }
    static get properties() {
      return {
        name:{
          type: String,
          value: "Said",
          observer:"changedName"
        },
        child:{
          type: String,
          value: "Luis"
        }
      };
    }
    changedName(new_value, old_value){
      console.info(` ${new_value} - ${old_value}`)
    }
  }
  customElements.define(PolymerElementOne.is, PolymerElementOne);
</script>
</dom-module>

<dom-module id="polymer-element-two">
<template>
     <style>
    :host {
      background-color: yellow;
      display: block;
      padding: 4px;
    }
  </style>
  <h2> I am a second componente  !!</h2>
  <input type="text" value="" >
  <h3>[[parentName]]</h3>
</template>
 <script>
   class PolymerElementTwo extends Polymer.Element {
     static get is() { return "polymer-element-two"; }
     static get properties() {
       return {   
        parentName:{
          type: String,
          notify: true
        }
       }
     }
  }
  customElements.define(PolymerElementTwo.is, PolymerElementTwo);
</script>
</dom-module> 

Polymer 1

https://codepen.io/saidmlx/pen/gyyLQW?editors=1000

https://codepen.io/saidmlx/pen/WzGxyX?editors=1000

https://codepen.io/saidmlx/pen/YvLxYB