polymer: 5. eventos

Cómo funcionan los eventos en polymer

Vincent Van Gogh

archivado en: JavaScript / 12 enero, 2016 / taller:

Polymer permite manejar los eventos de una forma cómoda y bastante ordenada. Se pueden definir de dos maneras. Una es mediante «listeners», escuchas, que se declaran cuando estamos registrando un componente. La fórmula es sencilla, en el campo listeners se van añadiendo pares de claves valor, en los que la clave está formada por el id del nodo y el evento asociado, como un click, y en el valor el nombre de la función que se invoca con ese evento.

listeners: {

idFoo.click: "funcionFoo",

idBar.change: "funcionBar"

}

Si no se especifica ningún id, el evento se asocia a todo el componente.

Por ejemplo, así crearíamos un componente con un botón que al ser pulsado lanza una función.

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

<dom-module id="x-custom">

<template>

<style>

.frog {

color: #009;

font-weight: bold;

}

</style>

<div id="blueFrog">

<p class="frog">Soy una rana azul</p>

<button id="croak">croar</button>

</div>

</template>

<script>

Polymer({

is: "x-custom",

listeners: {

"croak.click": "crazyCroak"

},

crazyCroak: function() {

alert("crooooooak");

}

});

</script>

</dom-module>

Retorno al tag

El sistema anterior plantea varios problemas, como la necesidad de que los ids se encuentren en el dom en el momento de lanzar las escuchas. Por ejemplo, si insertáramos un nuevo elemento en el ready...

ready: function() {

var element = document.createElement("button");

element.textContent = "otro boton";

element.setAttribute("id", "anotherButton");

this.$.blueFrog.appendChild(element);

},

... al quedar fuera del mapeo de ids automáticos que hace polymer que vimos en la entrada anterior, no podríamos engancharle un listener.

Situaciones similares a esta llevaron al equipo de angular a retomar la manera en que se lanzaban los eventos hace años, antes de que aparecieran los listener y que se popularizaran con jQuery, definiéndolos directamente en el tag correspondiente. De hecho, argumentan, ahora que es imposible toparse con un navegador con el javaScript deshabilitado, ya no es necesario separar el html del js de forma tan drástica. Y esta es precisamente la solución que ha adoptado este otro equipo de google.

De esta manera, mediante la fórmula on-nombreEvento, podemos bindear cualquier evento clásico (click, change, blur, focus, etcétera). Así, por ejemplo, podríamos refactorizar la ranita azul de antes para enganchar el evento en el tag.

<button id="croak" on-click="crazyCroak">croar</button>

No entraré ahora a analizar los aspectos teóricos de este sistema, si es más o menos limpio, pero es caso es que el que de momento funciona mejor en polymer.

Gesture events

Como hoy en día las webs y las aplicaciones web son multidispositivo, los desarrolladores de polymer han preparado una serie de eventos que valen tanto para escritorio como para dispositivos móviles. Es previsible que estos eventos, que llaman «gesture events», vayan aumentando y son los que deberíamos usar siempre que se ajusten a lo que necesitamos.

El más sencillo es tap, que equivale al click normal, con el que recibimos dos parámetros, el evento y sus coordenadas x e y.

...

<button id="croak" on-tap="crazyCroak">croar</button>

...

crazyCroak: function(event, coords) {

console.log("tap de " + event.path[0].tagName + " en las coordenadas " + coords.x + ", " + coords.x);

}

...

Además, de momento, tenemos otros tres: down y up, muy parecidos al anterior, que equivalen respectivamente al mousedown y el mouseup; y track, para el movimiento (por ejemplo el de un drag).

Custom events

Polymer también permite lanzar eventos propios usando el método fire. Aunque el ejemplo no es del todo correcto por razones que veremos luego, para que se entienda cómo funciona vamos a añadir un mosquito al componente...

<div id="redMosquito">

<p>Soy un mosquito rojo</p>

<button id="fly" on-tap="beginFly">volar</button>

</div>

El mosquito tiene un evento on-tap en el botón, que al ser pulsado lanzará el evento personalizado fly.

beginFly: function() {

this.fire('fly', "zámpame puedes");

},

Como segundo argumento de fire podemos poner cualquier cosa (una cadena, un objeto...), que luego podremos recuperar en el objeto que recibe el evento en la propiedad detail.

Ahora podemos capturar ese evento de alguna manera, por ejemplo en un listener.

listeners: {

'fly': 'eatMosquito'

},

eatMosquito: function(data) {

console.log(data.detail); // zámpame puedes

}

La escucha debe hacerse en este caso sobre el propio componente. Es decir, esto no funcionaría:

listeners: {

'fly': 'eatMosquito'

},

Decía que este ejemplo no es muy didáctico, ya que lo normal es usar los custom events para comunicar cosas desde el componente hacia fuera, ya sea este fuera otro componente o la página que lo acoge. Para que se entienda bien esto, vamos a hacer otro ejemplo.

Un input fantastico

Vamos a preparar un componente (fantastic-form) que contenga otro componente (fantastic-input), que será un input desde el que enviaremos un custom event cada vez que el usuario escriba algo. Desde el componente superior recogeremos el valor y lo mostraremos en la parte inferior. Algo así:

input-fantastico

Empezamos por el componente inferior. No es más que un input con un evento on-change que a su vez dispara un fire en el que enviamos lo que se ha escrito.

fantastic-input.html

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

<dom-module id="fantastic-input">

<template>

<input type="text" on-keypress="sendEvent" id="finput">

</template>

<script>

Polymer({

is: "fantastic-input",

sendEvent: function() {

var valueInput = this.$.finput.value;

this.fire("changeFantastic", valueInput);

}

});

</script>

</dom-module>

Luego, en el componente que lo acogerá, basta con recoger el evento.

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

<link rel="import" href="fantastic-input.html">

<dom-module id="fantastic-form">

<template>

<h4>Este es un input fantástico</h4>

<fantastic-input></fantastic-input>

<p id="contentFantasticInput"></p>

</template>

<script>

Polymer({

is: "fantastic-form",

listeners: {

'changeFantastic': 'changeInputFantastic'

},

changeInputFantastic: function(data) {

this.$.contentFantasticInput.textContent = data.detail;

}

});

</script>

</dom-module>

Bueno, pues de momento lo dejo aquí.

los ejemplos de esta entrada están en git

|| Tags: ,

valoración de los lectores sobre polymer: 5. eventos

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración negativa
  • 4.1 sobre 5 (7 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Los comentarios están cerrados.