> Manuales > Manual de Polymer 2

Qué es el binding y cómo lo configuramos en Polymer 2. Tipos de binding bidireccional y unidireccional. Interoperabilidad entre componentes.

En este artículo del Manual de Polymer 2 vamos a abordar el binding en Polymer 2. Como a estas alturas muchos lectores tendrán ya claro el concepto de binding, vamos a comenzar directos al grano, ofreciendo unas pequeñas y rápidas anotaciones para explicar cuál es el funcionamiento general del binding en Polymer 2 y su sintaxis.

Pero si tú todavía no tienes claro qué es el binding no te preocupes, porque en el resto del artículo ahondaremos en los conceptos para no dejar ni un detalle y de modo que puedas resolver todas tus dudas.

Así pues, vamos a comenzar con explicaciones objetivas y rápidas, que sirvan de referencia para todo el mundo.

Funcionamiento del binding en Polymer 2

El binding en Polymer funciona siempre transmitiendo los datos de padres a hijos. Un componente puede transmitir el valor de una de sus propiedades a cualquier elemento del template, así como a otros componentes que tenga como hijos.

Además el binding es configurable, permitiendo definir si se desea un binding de una dirección o de dos direcciones. El binding de una dirección es el que transmite de padres a hijos y el binding de dos direcciones es el que además transmite el valor en dirección contraria: desde el hijo hasta el padre.

Para definir si queremos binding de una dirección y de dos direcciones, utilizamos dos tipos de notaciones distintas:

Nota: Ojo con el binding de dos direcciones, puesto que es un poco más pesado para la aplicación, en términos de tiempo de procesamiento. Por eso en muchas ocasiones es preferible usar bindeo de una sola dirección y usar mecanismos como los eventos para producir el aviso a los padres cuando los hijos desean cambiar el valor de las propiedades. Hablaremos de esto más adelante en otros ejemplos cuando hayamos abordado el tema de los eventos en Polymer.

De momento es todo lo que te vamos a contar en el presente artículo sobre el binding en Polymer. Solo debes saber además que para que se produzca un binding ascendente en Polymer, aparte de usar las dobles llaves, necesitas que el componente que debe avisar al padre tenga definida la propiedad con el valor "notify" a "true". Hablaremos de esto más adelante también con otros ejemplos.

Nota: Para que quede claro, con respecto al binding de dos direcciones, debes entender que por mucho que tú lo uses al declarar el bindeo en el template, Polymer no siempre lo implementará y te hará un binding de una única dirección. Por ejemplo, también te ocurrirá cuando bindeas al contenido de una etiqueta HTML párrafo (etiqueta P). Por mucho que uses dobles llaves no servirá para nada, ya que ese párrafo no está preparado para avisar al padre hipotéticos cambios.

Si no tienes claro el concepto de binding o deseas ver ejemplos de binding en Polymer, sigue leyendo.

Qué es el binding

El binding es una herramienta base de muchas librerías y frameworks. Simplemente es un enlace, para asociar un mismo dato a diversos integrantes de una aplicación, de tal modo que si uno de ellos lo cambia, su valor cambie en los otros elementos que tienen ese dato bindeado.

El binding nos ahorra programar más de la cuenta, pues el propio Polymer será el encargado de hacer viajar el dato bindeado de un lugar a otro. Esto evita que tengamos que estar suscribiendonos a eventos, para saber en qué momento se modifica un dato y así realizar la operación de escritura manualmente en los elementos u objetos que lo comparten.

Básicamente encontraremos binding en dos situaciones. Prefiero verlas por separado, aunque realmente podríamos decir que es lo mismo con distintos matices.

Binding del componente al template

El caso más sencillo de binding se produce desde las propiedades de un componente hacia el template. Este ejemplo ya lo hemos observado en casos anteriores del Manual de Polymer 2, como en el componente del estado de ánimo del artículo de Propiedades y estado de los componentes en Polymer 2.

Al tener una propiedad declarada:

static get properties() {
  return {
    propiedadComponente: {
      type: String,
      value: 'Valor predeterminado'
    }
  };
}

Podremos bindearla, para mostrar su estado actual en el template:

<template>
  <p>
    Este valor está bindeado: "[[propiedadComponente]]"
  </p>
</template>

El valor de la propiedad "propiedadComponente" se volcará en el párrafo de este template, mostrando automáticamente el nuevo valor cuando el dato cambia.

Nota: La notación de los corchetes "[[]]" en este caso produce un binding de una sola dirección. Aunque en este caso, al bindear a un texto de un template realmente no podría existir binding de dos direcciones, por lo que tampoco tendría mucho sentido usar las dobles llaves.

Binding entre componentes

Además puede darse el binding entre diversos componentes. Por ejemplo, lo tenemos aquí:

<template>
  <paper-input label="¿cómo te encuentras?" value="{{miAnimo}}"></paper-input>

  <estado-animo animo="[[miAnimo]]"></estado-animo>
</template>

En este template tenemos dos ejemplos de binding entre componentes y en uno hemos usado bindeo de una dirección y en otro bindeo de dos direcciones. Todo tiene su sentido.

Por un lado tenemos un paper-input, que es un campo de texto donde se puede escribir una cadena de caracteres. El valor del campo de texto se está escribiendo en la propiedad "miAnimo", por medio de un binding escrito sobre el atributo "value" del paper-input.

Nota: en este caso, con la notación de las dobles llaves "{{}}" estamos produciendo un binding de dos direcciones: value="{{miAnimo}}". Aquí es necesario el binding de dos direcciones para que, cuando alguien escriba algo en el campo de texto, el valor nuevo que se ha escrito viaje automáticamente al padre.

Como segundo ejemplo de binding tenemos la propiedad "miAnimo" bindeada al componente "estado-animo". Eso indica que, cada vez que cambie "miAnimo" porque el usuario escriba otra cosa en el paper-input, se actualizará el valor bindeado al componente "estado-animo".

Nota: en este nuevo caso tenemos un binding de una dirección: animo="[[miAnimo]]". En este caso es suficiente de una dirección porque el componente estado-animo no tiene posibilidad de cambiar el valor de la propiedad bindeada. Y aunque lo cambiase, el componente padre no necesita enterarse de nada.

Código completo de este ejercicio

Para acabar, vamos a ver el código completo del componente que hemos creado para explicar el binding. En realidad es una modificación del ejemplo que explicamos en el anterior artículo, donde hablamos sobre la instalación de Polymer 2 y su CLI.

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

<dom-module id="test-cli-app">
<template>
  <style>
    :host {
      display: block;
    }
  </style>
  <estado-animo animo="{{estadoAnimo}}"></estado-animo>

  <paper-input label="¿cómo te encuentras?" value="{{estadoAnimo}}"></paper-input>

  Este valor está bindeado: "[[estadoAnimo]]"
</template>

  <script>
    class TestCliApp extends Polymer.Element {
      static get is() { return 'test-cli-app'; }
      static get properties() {
        return {
          estadoAnimo: {
            type: String,
            value: 'de rechupete'
          }
        };
      }
    }

    window.customElements.define(TestCliApp.is, TestCliApp);
  </script>
</dom-module>

Obviamente, un tema tan importante como el binding incluye muchas otras cosas que no hemos abordado en este artículo. Pero no te preocupes, con lo que hemos visto aquí podremos ir funcionando bien, hasta que lleguemos a un nivel más avanzado en el manual de Polymer 2.

Más adelante en la sección de binding podremos aprender muchas otras cosas interesantes, como hacer componentes que avisen a los padres de cambios en sus propiedades, bindear a atributos nativos de elementos de HTML, etc.

Miguel Angel Alvarez

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

Manual