Introducción al binding en Polymer

  • Por
Qué es el binding, una de las grandes herramientas que nos permite muchas facilidades en el desarrollo y la interoperabilidad entre componentes. Ejemplos de implementación de bindings en Polymer.

Una de las cosas más potentes que nos ofrece la librería Polymer es la operación que se conoce como binding. Si ya sabes lo que es el binding de otras librerías o frameworks no habrá mucho que explicar conceptualmente hablando. Pero si no es el caso te diremos que binding es una operación de enlace, por medio de la cual un dato puede estar relacionado, mostrando su mismo valor en dos zonas distintas de la aplicación. La gracia es que, mediante el proceso de binding, si ese dato cambia en un lado de la aplicación, el cambio se desencadena de modo que se actualicen todos los lugares donde se está visualizando.

Al que viene de AngularJS seguro que una de las cosas que le impactaron es el binding en dos direcciones. También existe en Polymer y funciona de manera muy similar. Si es tu caso seguramente te sentirás como en casa al acercarte a Polymer.

El binding es muy amplio en Polymer, produciéndose a muchos niveles. Tenemos binding de un dato dentro del mismo componente, binding entre componentes, binding en una dirección y en dos direcciones, etc. Iremos viéndolo en este artículo y en los sucesivos. Realmente a lo largo de todo el manual hacemos uso del binding constantemente. Incluso aunque solo ahora abordamos este asunto de manera particular, ya hemos realizado operaciones de "bindeo" en varias ocasiones.

Binding dentro de un componente

Comenzaremos tratando el binding de un valor dentro del mismo componente, ya que es algo bastante sencillo de explicar y de ver.

Pongamos que tenemos un dato declarado mediante una propiedad:

Polymer({
  is: "ejemplo-binding",
  properties: {
    titular: {
      type: String,
      value: 'Esto es un titular'
    }
  }
});

Si queremos mostrar ese dato en nuestro componente lo bindeamos en el template mediante la expresión de las dos llaves de inicio y de cierre.

<template>
  <h1>{{titular}}</h1>
</template>

Cuando cambie la propiedad "titular" (algo que puede pasar por diversos motivos, como por ejemplo un script, respuesta a un evento o porque desde fuera nos actualicen esa propiedad) automáticamente cambiará el titular H1 del componente.

Ahora, en nuestro componente podemos tener ese binging hacia la propiedad "titular" en otros sitios.

<template>
  <h1>{{titular}}</h1>
  <paper-input label="Cambia el titular" value="{{titular}}"></paper-input>
</template>

En nuestro componente "paper-input" tenemos el value del campo bindeado al titular.

Nota: Por si no lo sabes, un componente "paper-input" es como un elemento "input" de toda la vida, solo que decorado con el diseño definido en "Material Design". Este, como muchos otros componentes, se encuentra disponible en el catálogo de elementos de Polymer.

Ahora, si cambia la propiedad, cambiará automáticamente en ambos lugares del template, en lo que hay escrito en el encabezamiento H1 y en lo que hay escrito dentro del "paper-input".

Bindeo de una y de dos direcciones

En nuestro componente hasta el momento hemos colocado dos bindings y ya tenemos un binding de una y de dos direcciones (one way & two way). Por si no ha quedado claro y antes de explicarlo con detalle, veamos el código completo de nuestro componente.

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

<dom-module id="ejemplo-binding">
<template>
  <style>
    :host {
      display: block;
    }
  </style>
  <h1>{{titular}}</h1>
  <paper-input label="Cambia el titular" value="{{titular}}"></paper-input>
</template>
  <script>
Polymer({
  is: "ejemplo-binding",
  properties: {
    titular: {
      type: String,
      value: 'Esto es un titular'
    }
  }
});
  </script>
</dom-module>

Bindeo de 1 dirección:
Es cuando los datos viajan solo en un sentido. Es decir, enviamos los datos hacia un elemento, pero si cambian dentro de ese elemento no se propagan.

Lo tienes en el caso del titular H1. En realidad en este caso es algo marcado por la propia naturaleza de la etiqueta H1, puesto que lo que hay escrito dentro del encabezamiento no es un contenido editable de ninguna manera. En ese encabezamiento los cambios van solo desde fuera hacia dentro. No hay como alterar el dato dentro del encabezamiento, luego no hay binding desde él hacia fuera.

Por motivos de rendimiento en Polymer es posible indicar de manera explícita un binding en una sola dirección, incluso en el elementos de naturaleza editable. Esto se hace con los corchetes en lugar de las llaves, como enseguida veremos.

Bindeo de dos direcciones:
Es cuando los datos viajan desde fuera del componente hacia dentro y desde dentro del componente hacia fuera.

Lo tienes en el caso del paper-input. Debido a que es un campo editable, si se cambia su contenido se alterará el valor de la propiedad "titular" y por ello los cambios saldrán hacia afuera, propagándose hacia todos los lugares donde se encuentre bindeado este dato.

Definir el bindeo de una dirección de manera explícita

En lugares donde se puede aplicar el bindeo en dos direcciones, porque sean elementos o componentes donde pueda llegarse a alterar el valor de las propiedades enlazadas, somos capaces de definir de manera explícita un bindeo de una única dirección.

Lo observaríamos si cambiamos las dos llaves por dos corchetes en el binding del paper-input:

<paper-input label="Cambia el titular" value="[[titular]]"></paper-input>

En este caso, si se cambia el contenido del campo de texto, su nuevo valor no viajará hacia afuera y los otros elementos que estén mostrando ese dato no se actualizarán.

Nota: Aunque parezca una desventaja el binding de una única dirección es muy interesante disponer de él, porque no siempre se necesita un enlace a dos bandas. En el caso que no sea necesario podemos simplemente ahorrar esos recursos a Polymer, optimizando el uso de la aplicación. Sin embargo, donde no hay posibilidad de binding en dos direcciones, como era el caso del encabezamiento H1, Polymer no necesita que le indiques el binding de una dirección de manera explícita, porque siempre será de una única dirección por la naturaleza del elemento.

Binding desde fuera hacia dentro del componente

Cualquier componente puede recibir datos desde fuera a sus propiedades. Esto es algo que ya hemos realizado en diversas ocasiones a lo largo del manual.

Para nuestro componente de ejemplo, podemos cargarle el valor inicial de la propiedad "titular" por medio de un atributo con el mismo nombre.

<ejemplo-binding titular="Este es el valor definido desde fuera"></ejemplo-binding>

En este caso hemos cargado un valor literal, pero ese valor también podría venir de un binding. Por ejemplo este componente podríamos usarlo dentro de otro componente (o dentro de un template "dom-bind" que veremos más adelante) y desde fuera poblar la propiedad "titular" por medio de otra propiedad que tengamos allí.

Nota: También puede haber tránsito de la información desde dentro del componente hacia afuera. Eso lo veremos en el siguiente artículo.

Propiedades readOnly

Podemos modificar el comportamiento anterior, indicando que alguna propiedad es "readOnly", de solo lectura. Es algo tan sencillo como indicarlo al declarar la propiedad.

properties: {
  titular: {
    type: String,
    value: 'Esto es un titular',
    readOnly: true
  }
}

Con esto conseguimos que, aunque nos asignen desde fuera valores o nos bindeen propiedades, en el interior de un componente no se acepten dichos valores definidos de manera externa.

El tema del binding es bastante amplio y todavía hay bastante por ver, aunque seguro que con lo visto hasta ahora ya te has hecho una buena idea de sus importantes posibilidades. En el siguiente artículo veremos, entre otras cosas, otra de las propiedades relacionadas con el binding, que es "notify", para permitir que los cambios de un bindeo viajen hacia fuera de un componente.

Autor

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.

Compartir