Estudiamos en profundidad el registro de las propiedades en componentes Polymer y todas sus opciones de declaración. Detallamos las propiedades computed.
Las propiedades de los elementos Polymer son una de las principales herramientas de cara al desarrollo de Web Components. El artículo anterior del Manual de Polymer, ya proporcionamos bastante información las propiedades en Polymer. Ahora vamos a ser un poco más formales y documentar con mayor detalle algunos de los datos que ya introdujimos anteriormente.
Nos centraremos en el registro o declaración de propiedades, que contiene una larga lista de posibilidades de configuración que debemos conocer y aprovechar en el día a día del desarrollo con esta librería Javascript.
En el pasado artículo vimos que en el objeto "properties", que enviamos en el registro de un componente Polymer, debíamos declarar una a una cada propiedad que queremos usar.
En esa declaración de la propiedad, indicada con bajo el objeto "properties", podemos hacer cosas como definir su tipo, su inicialización, etc.
Alternativas para la declaración de propiedades
Ya sabiendo todo eso, comenzamos ahora con un listado de los item que es posible configurar para cada propiedad declarada.
- type: Indicamos el tipo de dato que va a contener esta propiedad. En Polymer podemos usar los siguientes tipos de datos, nativos de Javascript: Boolean, Number, String, Array, Object y además Date.
- value: es el valor de inicialización que asignamos a una propiedad, que será configurado de manera predeterminada. Ese valor ya vimos en el pasado artículo que se puede cambiar de manera imperativa, simplemente asignando otro mediante Javascript, o de manera declarativa, al indicarlo en el HTML.
El valor puede ser un literal, como podemos ver en el código siguiente:
properties: {
propiedad1: {
type: Boolean,
value: true
}
}
También value puede estar asociado a un función que devuelva aquel valor con el que debemos inicializar la propiedad de manera predeterminada. En este caso, la función se ejecutará cuando se genere una instancia del componente, para asignar el valor que corresponda. Este sería el código para asignar un valor por medio de una función:
properties: {
personas: {
type: Array,
value: function(){ return ["mario", "gerardo"]; }
}
}
Este tipo de construcción es muy habitual en el caso de propiedades de tipo array y objeto, dado que la función permite que el array u objeto sea propio e independiente para cada instancia del componente.
- reflectToAttribute: Esta propiedad permite que, cuando desde dentro del componente o desde un Javascript externo, se cambie el valor de una propiedad, también se refleje en el código HTML del componente, cambiando su valor. Puede recibir true o false y la reflexión hacia el atributo se dará en caso positivo. Dicho de otra manera, la propiedad en el HTML del componente se sincronizará con el valor que tenga la propiedad en cada instante dentro del componente.
- readOnly: Es otro boleano, que indica si esta propiedad se puede alterar o no desde medios externos, como podría ser una asignación o un bindeo.
- notify: Esta declaración es muy importante para el binding, del que solo hemos introducido el concepto todavía. En concreto con notify (al que asignamos también un valor boleano) puedes definir si quieres que se notifique hacia afuera los cambios en una propiedad. De manera predeterminada los componentes Polymer no notifican a sus padres (aquellos componentes donde están incluidos) los cambios en sus propiedades. Asignando true a notify conseguimos que una propiedad notifique hacia arriba (al padre) los cambios en una de sus propiedades, algo como decimos necesario para producirse el "two-way-binding" que nos proporciona Polymer.
- computed: Esta es otra de las declaraciones de uso común. Nos sirve para indicarle que el dato o valor que guarda una propiedad está computado, es decir, que para conocer su valor se necesita realizar una operación. Le indicamos como valor el nombre del método que realizará el cómputo. En este mismo artículo explicamos con más detalle esta declaración un poco más adelante.
- observer: Es otro string al que le asignamos el nombre de una función. Esta función, o mejor dicho método del componente, se ejecutará cada vez que cambie el valor de esta propiedad. Dicho de otro modo, observer sirve para indicar el método que debe ejecutarse cada vez que el valor de la propiedad cambie.
Todas las alternativas para declarar propiedades son útiles en innúmeros casos, sin embargo hay unas que se usan más habitualmente que otras. Ahora vamos a ver un ejercicio sencillo de componente que nos ilustre el funcionamiento de algunas de las cosas que hemos aprendido, pero antes vamos a hablar con detalle de una de las declaraciones anteriores.
Declaración computed
En ocasiones las propiedades en un componente pueden ser computadas. Esto quiere decir que nosotros calcularemos su valor en función de otras propiedades.
Hay muchos casos de propiedades computadas en la vida real. Por ejemplo, el nombre completo de una persona, es una unión del nombre de pila y los apellidos. La letra del NIF de personas físicas en España se puede calcular en función de su número de DNI (Documento Nacional de Identidad). El área de una circunferencia se puede calcular en función de su radio. Etc.
Pues bien, en Polymer las propiedades "computed" son aquellas que se pueden calcular en función de otros datos y su valor cambiará cada vez que cambian estos datos. Por ejemplo en el caso de una circunferencia, se calculará el área en función de su radio y si cambia el radio el valor del área tendrá que cambiar instantáneamente.
A la hora de definir una propiedad computada debemos indicar la declaración "computed", indicando como valor una cadena con el nombre del método que realizará la computación junto con sus parámetros, que podrán ser los nombres de otras propiedades. Para que el valor computado se altere en cada instante, esa función se ejecutará cada vez que los valores de las funciones indicadas en los parámetros cambien.
properties {
radio: {
type: Number,
value: 1
},
area: {
type: Number,
computed: 'calcularArea(radio)'
}
}
En este caso vemos que "area" es la propiedad computada. El método "calcularArea" que debemos crear en el componente recibirá el "radio", que es otra propiedad del Polymer que se necesita para calcular el área. Cada vez que la propiedad "radio" cambie se invocará de nuevo a la función calcularArea() con el nuevo valor.
Polymer de ejemplo: romper-cadena
Ahora sí, vamos a crear nuestro componente de ejemplo para dar un repaso a lo aprendido hasta el momento. Se trata de un componente que sirve para romper una cadena de texto, sin quebrar sus palabras por la mitad. Se puede usar en muchos casos, como en descripciones de items, extractando esa descripción en función de un texto más largo.
En este caso la gracia está en la propiedad computada "recorte", que almacena el valor que debemos mostrar, producido al recortar el texto largo con una longitud dada. Por tanto nos salen tres propiedades:
- El texto largo, sobre el que tenemos que recortar algo
- La longitud de caracteres, evitando que dicha longitud produzca recortes en las palabras. (si se diera el caso simplemente recortamos hasta la última palabra que se pueda ver entera)
- El recorte, que será la propiedad computada
El código completo está a continuación:
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="rompe-cadena">
<template>
<span>{{recorte}}</span>
</template>
<script>
Polymer({
is: 'rompe-cadena',
properties: {
len: {
type: Number,
value: 20
},
str: {
type: String,
value: ''
},
recorte: {
type: String,
computed: 'calculaRecorte(len, str)'
}
},
calculaRecorte(len, str){
if (str.length <= len) {
return str;
}
var recortada = str.substr(0, len);
return recortada.substr(0, Math.min(recortada.length, recortada.lastIndexOf(' '))) + '...';
}
});
</script>
</dom-module>
Nuestro template simplemente muestra la propiedad {{recorte}}, bindeando gracias a las dos llaves de apertura y cierre. Repara en el detalle que la propieddad que estamos bindeando al template, y que por tanto se verá en el espacio donde se encuentre este componente Polymer, es aquella que hemos declarado como computed. Por tanto, lo que se mostrará aquí será el valor una vez computado, con la función indicada para ello.
Fíjate en las propiedades señaladas, observando que en el caso de la propiedad "len" hemos asignado un valor predeterminado para el recorte. En el caso de "str" (que es la cadena original antes del recorte), su valor predeterminado es la cadena vacía.
Luego en la propiedad computada "recorte" tenemos la declaración computed, indicando el nombre de la función que realizará el cálculo y los datos que necesita para completarlo.
Esos datos que se pasan por parámetro son nombres de propiedades del componente, las necesarias para hacer el cálculo y las que marcan la necesidad de volver a invocar esa función cada vez que cambien.
Ahora puedes ver el código de la página con la que probamos el componente.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Probando vista-fecha</title>
<link rel="import" href="rompe-cadena.html">
</head>
<body>
<h1>Probando rompe-cadena</h1>
<p>
<rompe-cadena str="Lo que el viento se llevó"></rompe-cadena>
</p>
<p>
<rompe-cadena str="Las dos caras de la moneda" len="10"></rompe-cadena>
</p>
</body>
</html>
Videotutorial propiedades computed
Ahora tienes un vídeo que explica cómo se declaran y utilizan las propiedades "computed", realizando el ejemplo anterior del componente que rompe la cadena, paso por paso.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...