Polymer
Tabla de contenido
- Librerias a importar
- Estructura básica de un componente
- Data binding
- Estructura dom-repeat
- Estructura dom-if
- Métodos
- Eventos
- Arrays
- Anidar componentes
- Como pasar propiedades entre componentes
- Notify
- Observer
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"}
- 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