Ciclo de vida en los Web Components

  • Por
Qué es el ciclo de vida en los Web Components y cómo podemos ejecutar acciones en diferentes estados de los componentes.

Los Web Components son una tecnología incipiente que va a cambiar el modo con el que se desarrollan las aplicaciones para navegadores. Ya hemos empezado a hablar sobre ellos en otras ocasiones en el Manual de Web Components, así que nos centraremos ahora en un tema específico y clave para los desarrolladores, como es su ciclo de vida.

El ciclo de vida es parte de la especificación de los Web Components y básicamente incluye diversos estados que pueden tener los Custom Elements a lo largo de su existencia. Desde la creación de un componente, su inserción dentro del documento web hasta su retirada, por poner varios ejemplos. Por medio de estos estados, por los que pasa cualquier componente, podemos personalizar su comportamiento en circunstancias muy concretas.

Básicamente el ciclo de vida está ahí para servir de utilidad a los desarrolladores de componentes, ya que permiten escribir código Javascript que será ejecutado cuando el componente va pasando por sus diferentes estados. Esta operación se realiza por medio de lo que se conoce como funciones "callback": funciones que son declaradas pero que no se ejecutan hasta que pasan ciertas cosas.

Estados del ciclo de vida de un componente

Para comenzar vamos a describir los estados de un componente que definen su ciclo de vida:

  • Created: Ocurre cuando el elemento se crea, pero ojo, no tiene que ver con que el elemento se muestre. Es como su instanciación en memoria de Javascript. Cada elemento de un tipo de custom element generado, lanza el método created.
  • Attached: Ocurre cuando un elemento que había en la memoria de Javascript se inyecta dentro de un documento, o sea, pasa a formar parte del DOM de la página.
  • Detached: Ocurre cuando un elemento se quita del DOM, se retira del documento y por tanto desaparece de la página.
  • Atribute Changed: Ocurre cuando uno de sus atributos cambia de valor.

Nota: Estos son los estados del ciclo de vida de los custom elements en Javascript estándar, aunque algunas librerías basadas en Web Components incorporan otros adicionales.

Asociar comportamientos a instantes del ciclo de vida de custom elements

Puedes ver todos esos estados son como si fueran eventos que ocurren durante la vida de un componente. Como a los eventos, seremos capaces de asociar funciones manejadoras, que se encargan de producir comportamientos personalizados para cada suceso. En este caso llamamos a esas funciones con el término "calback", usado en el estándar como ahora podrás ver.

Ahora veremos el código del registro de un componente en el que usaremos los diversos métodos callback del ciclo de vida. Pero para entenderlo te sugerimos la lectura del artículo del estándar de los Custom Elements, en el que se explicaron ya muchas cosas que aquí vamos a dar por sabidas.

// Creo un nuevo objeto para registrar un componente, generando un nuevo prototipo
  var elemento = Object.create(HTMLElement.prototype);

  // Defino una función callback para el instante del ciclo de vida "created"
  elemento.createdCallback = function() {
    console.log('se ha creado un elemento');
  };

  // Defino una función callback para el instante del ciclo de vida "attached"
  elemento.attachedCallback = function() {
    console.log('se ha añadido un elemento al DOM');
  };

  // Defino una función callback para el instante del ciclo de vida "detached
  elemento.detachedCallback = function() {
    console.log('se ha retirado un elemento del DOM');
  };

  // Defino una función callback para el instante del ciclo de vida "attributeCanged"
  elemento.attributeChangedCallback = function(attr, oldVal, newVal) {
    console.log('Cambiado ', attr, ' al valor: ', newVal);
  };

  // Este es el código para registrar el componente, en el que indicamos su prototipo que acabamos de definir
  document.registerElement('ciclo-de-vida', {
      prototype: elemento
  });

Apreciando los estados del ciclo de vida

Solo con que uses un elemento, colocando la etiqueta HTML 'ciclo-de-vida' éste se generaría y se adjuntaría al DOM, con lo que ya se pondrán en marcha los métodos del ciclo de vida, con sus correspondientes console.log().

<ciclo-de-vida></ciclo-de-vida>

Nota: Obviamente, para que ese elemento funcione debe conocerse previamente el elemento, por lo que el script para registrarlo visto en el punto anterior debería aparecer antes en el código HTML. (Mira al final el código completo del ejercicio).

Quizás con nuestro ejemplo te sorprenda que no observarás cambios en la página, porque el elemento del ejemplo no tiene template, pero sí deberías ver los mensajes si abres la consola Javascript.

  • se ha creado un elemento
  • se ha añadido un elemento al DOM

Para ver otros métodos del ciclo de vida necesitas el código de algunas funciones Javascript de manipulación del DOM. Para ello hemos colocado tres botones que invocan tres manipulaciones diferentes sobre el DOM, que provocarán nuevos mensajes a la consola de Javascript.

<button id="cambiaAtr">Cambia Atributo</button>
<button id="quitarDOM">quitar el elemento del DOM</button>
<button id="crearElemento">crear un elemento,  solo en memoria</button>

Esos eran los tres botones, a los que les colocamos tres manejadores de eventos para realizar cosas con elementos:

document.getElementById('cambiaAtr').addEventListener('click', function() {
  document.querySelector('ciclo-de-vida').setAttribute('data-test', 'test-value');
});
document.getElementById('quitarDOM').addEventListener('click', function() {
  document.body.removeChild(document.querySelector('ciclo-de-vida'));
});
document.getElementById('crearElemento').addEventListener('click', function() {
  document.createElement('ciclo-de-vida');
});

Código completo

Eso es todo lo que necesitas para practicar con los mecanismos del ciclo de vida de los custom elements. Ahora para aclarar posibles dudas dejamos el código completo del ejercicio.

Nota: Recuerda que, a pesar que esto sea todo Javascript nativo, solo funcionará para los navegadores que ya implementan el estándar de los Web Components. Para navegadores que aún no lo tienen disponible simplemente habría que usar el correspondiente polyfill, del que ya hemos hablado anteriormente en este manual.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Test del ciclo de vida de custom elements</title>
  <script>
  (function() {
  // Creo un nuevo objeto para registrar un componente, generando un nuevo prototipo
  var elemento = Object.create(HTMLElement.prototype);

  // Defino una función callback para el instante del ciclo de vida "created"
  elemento.createdCallback = function() {
    console.log('se ha creado un elemento');
  };

  // Defino una función callback para el instante del ciclo de vida "attached"
  elemento.attachedCallback = function() {
    console.log('se ha añadido un elemento al DOM');
  };

  // Defino una función callback para el instante del ciclo de vida "detached
  elemento.detachedCallback = function() {
    console.log('se ha retirado un elemento del DOM');
  };

  // Defino una función callback para el instante del ciclo de vida "attributeCanged"
  elemento.attributeChangedCallback = function(attr, oldVal, newVal) {
    console.log('Cambiado ', attr, ' al valor: ', newVal);
  };

  // Este es el código para registrar el componente, en el que indicamos su prototipo que acabamos de definir
  document.registerElement('ciclo-de-vida', {
      prototype: elemento
  });
  }());
  </script>
</head>
<body>
  <ciclo-de-vida></ciclo-de-vida>
<button id="cambiaAtr">Cambia Atributo</button>
<button id="quitarDOM">quitar el elemento del DOM</button>
<button id="crearElemento">crear un elemento,  solo en memoria</button>

  <script>
  window.onload = function() {
  document.getElementById('cambiaAtr').addEventListener('click', function() {
    document.querySelector('ciclo-de-vida').setAttribute('data-test', 'test-value');
  });
  document.getElementById('quitarDOM').addEventListener('click', function() {
    document.body.removeChild(document.querySelector('ciclo-de-vida'));
  });
  document.getElementById('crearElemento').addEventListener('click', function() {
    document.createElement('ciclo-de-vida');
  });
  }
  </script>
</body>
</html>

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