viernes, 15 de diciembre de 2017

Siguiendo con la Introducción a Polymer 2

Lo de los webcomponents es algo genial: Dividimos la complejidad en pequeños pequeños, cuyas soluciones pueden ser reutilizables. El siguiente paso es verificar no sólo como trabaja la relación padre-hijo, sino la de aquellos componentes que pudieran tener el mismo nivel jerárquico en un momento dado.

Sobre nuestro ejemplo anterior, haremos un nuevo componente vt-etiqueta
mkdir src/componentes/etiquetas/
El contenido del fichero src/componentes/etiquetas/vt-etiqueta.html es el siguiente:
<link href="../../../bower_components/polymer/polymer-element.html" rel="import"></link>
<dom-module id="vt-etiqueta">
    <template>
        <style>
        :host {
            display: block;
        }
        </style>
        <label>Etiqueta componente: [[contenido]] </label>
    </template>
    <script>
        class VtEtiqueta extends Polymer.Element {
            static get is() {
                return 'vt-etiqueta';
            }
            static get properties (){
                return {
                    contenido: {
                        type: String,
                    }
                }
            }
        }
        window.customElements.define(VtEtiqueta.is, VtEtiqueta);
    </script>
</dom-module>
Luego, hemos de añadirlo en el componente polymer-muestra-inicial-app, que tiene la mayor jerarquía en nuestra aplicación. Primero un import en forma de etiqueta <link> y luego una etiqueta propiamente dicha. El código de src/polymer-muestra-inicial-app/polymer-muestra-inicial-app.html queda ahora de la siguiente forma:
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="/src/componentes/entradas/vt-entrada.html">
<link rel="import" href="/src/componentes/etiquetas/vt-etiqueta.html">

<dom-module id="polymer-muestra-inicial-app">
    <template>
        <style>
        :host {
            display: block;
        }
        </style>

        <h2>Hello [[prop1]]!</h2>
        <vt-entrada contenido="{{contenido}}"></vt-entrada>
        <vt-etiqueta contenido="[[contenido]]"></vt-etiqueta>
    </template>

    <script>
    /**
     * @customElement
     * @polymer
     */
    class PolymerMuestraInicialApp extends Polymer.Element {
        static get is() { return 'polymer-muestra-inicial-app'; }
        static get properties() {
            return {
                prop1: {
                    type: String,
                    value: 'polymer-muestra-inicial-app'
                },
                contenido:{
                    type: String,
                    value: 'Desde componente host'
                }

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

El contenido de vt-etiqueta, expuesto en la propiedad contenido será actualizado desde nuestro componente anterior, vt-entrada.
Para que eso suceda, modificamos la definición de este último en src/componentes/entradas/vt-entrada.html, configurando el atributo notify de dicha propiedad a true. Una pequeña línea no debería ser razón para volver a presentar todo el código, pero es gratis:
<link rel="import" href="../../../bower_components/polymer/polymer-element.html">
<dom-module id="vt-entrada">
    <template>
        <style>
            :host {
                display: block;
            }
        </style>
        <input type="text" value="{{contenido::input}}">
        <p> Este es nuestro contenido escribiente: [[contenido]]</p>
    </template>
    <script>
        class VtEntrada extends Polymer.Element {
            static get is() {
                return 'vt-entrada';
            }
            static get properties() {
                return {
                    contenido: {
                        type: String,
                        notify: true,
                    }
                }
            }
        }

        window.customElements.define(VtEntrada.is, VtEntrada);
    </script>
</dom-module>
Al escribir en la caja de texto del componente vt-entrada, el contenido de vt-etiqueta se va modificando.

Para tener en mente según lo visto:

  • Los binding [[propiedad]] son unidireccionales. (Padre al hijo)
  • Los binding {{propiedad}} son bidireccionales. (Padre al hijo y viceversa)
  • Para que esto último funcione con propiedades que han de modificarse en un componente hijo, es preciso que la propiedad tenga configurada notify: true en dicho hijo.
Sí, los componente son bastante reutilizables
Para ejemplo, basta con agregar otro vt-entrada en src/polymer-muestra-inicial-app/polymer-muestra-inicial-app.html cuyo contenido haga binding bidireccional con prop1, que es la propiedad que muestra del Hola Mundo de nuestra aplicación. Es un pequeño cambio, pero como copiar y pegar es sencillo:
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="/src/componentes/entradas/vt-entrada.html">
<link rel="import" href="/src/componentes/etiquetas/vt-etiqueta.html">

<dom-module id="polymer-muestra-inicial-app">
    <template>
        <style>
        :host {
            display: block;
        }
        </style>

        <h2>Hello [[prop1]]!</h2>
        <vt-entrada contenido="{{contenido}}"></vt-entrada>
        <vt-entrada contenido="{{prop1}}"></vt-entrada>
        <vt-etiqueta contenido="[[contenido]]"></vt-etiqueta>
    </template>

    <script>
    /**
     * @customElement
     * @polymer
     */
    class PolymerMuestraInicialApp extends Polymer.Element {
        static get is() { return 'polymer-muestra-inicial-app'; }
        static get properties() {
            return {
                prop1: {
                    type: String,
                    value: 'polymer-muestra-inicial-app'
                },
                contenido:{
                    type: String,
                    value: 'Desde componente host'
                }

            };
        }
    }
    
    window.customElements.define(PolymerMuestraInicialApp.is, PolymerMuestraInicialApp);
    </script>
</dom-module>
Desde el navegador, lo vemos de la siguiente forma:
Seguimos sin hacer que esto parezca algo mínimamente serio, pero al menos se esta volviendo cada vez más divertido.

No hay comentarios:

Publicar un comentario

Otros apuntes interesantes

Otros apuntes interesantes