Uso del ciclo de vida AttributeChangedCallback en componentes web
Resumen
¿Qué es el ciclo de vida AttributeChangeCallback?
En el fascinante mundo de los componentes web, entender cómo monitorizar y manejar cambios en los atributos es esencial. Una manera sofisticada de hacerlo es a través del ciclo de vida llamado AttributeChangeCallback. Este permite a los desarrolladores observar y reaccionar a cualquier modificación de atributos en un componente web, promoviendo la flexibilidad y adaptabilidad del mismo.
¿Cómo configuramos el observador de atributos?
Antes de sumergirnos en el ciclo de vida de AttributeChangeCallback, necesitamos establecer un observador de atributos. Este observador define específicamente qué atributos debe vigilar nuestro componente web. Los pasos son:
Crear un método estático: Utilizamos static get observedAttributes() para especificar los atributos a monitorizar.
Definir los atributos de interés: Sólo los atributos listados serán observados. Si se añaden otros, se ignorarán a menos que se incluyan en esta lista.
¿Cómo funciona el AttributeChangeCallback?
El método attributeChangedCallback es donde ocurre la magia. Este ciclo de vida permite que nuestro componente responda dinámicamente a los cambios en los atributos observados.
Implementación del método attributeChangedCallback
Escuchar cambios en los atributos: Este método toma tres parámetros principales: attribute, oldValue, y newValue.
Validar y actualizar: La función compara el atributo actual con los establecidos y, si detecta un cambio, actualiza el valor del atributo.
¿Por qué es importante el mecanismo de la comparación de atributos?
La comparación detallada dentro de attributeChangedCallback es vital porque garantiza que solo se actúe sobre aquellos atributos relevantes para el componente. Este enfoque ayuda a mantener un rendimiento óptimo y facilita la reutilización del componente en diversos contextos sin necesidad de realizar modificaciones internas.
¿Cómo maximizar la reutilización del componente?
Al usar attributeChangedCallback, no solo optimizas cómo los atributos influyen en la interfaz de usuario. También se refuerza la arquitectura del componente para que sea más independiente y flexible.
Reutilización en múltiples proyectos: Puedes proporcionar un manual básico o lista de atributos que los desarrolladores deben usar, asegurando que pueden adaptar el componente sin intervenir su código base.
Dinamismo y flexibilidad: Gracias a la observación de atributos, los cambios en el contenido son más naturales y automáticos, imitando la versatilidad de las piezas de un LEGO.
¿Qué viene luego?
Aunque ahora sabemos cómo manejar atributos de componente de forma dinámica, el siguiente paso es enriquecer nuestros componentes con estilos versátiles. Exploraremos cómo aplicar estilos que se adapten a cualquier contexto, sin dejar que el shadowDOM limite nuestra creatividad. ¡Continuemos aprendiendo y mejorando nuestras habilidades de desarrollo web!
Perdón por la molestia pero podrías ampliar un poco mas y explicar el error y tu solución, busque en google pero no termine de entender. Gracias.
Hola Adrián, el error proviene de observedAttributes ya que esta escuchando cualquier cambio de esos 3 atributos. Entonces genera un loop y manda el error en consola.
Gracias... ya tenía rato debbugeando sin exito que era lo que pasaba... y las soluciones proponen otros compañeros no me funcionaba tampoco... y era por el nombre de la propiedad title
Se entendió el concepto pero el video no lo ejemplifica. El valor del atributo no estaá cambiando los el valor dentro del componente, se hizo un trabajo de edición para ocultar este hecho, puntualmente este video me decepcionó como ejemplo
Adhiero
Algo que de pronto no queda muy claro en esta clase sobre attributeChangedCallback() es que es un metodo util para mutar o actualizarlas las propiedades del componente en tiempo de ejecucion, una aproximacion a lo que podria ser un state del componente. Encontre este recurso donde se ve un ejemplo (un contador) un poco mas claro
MY NOTES FOR ATTRIBUTE CHANGED CALLBACK
classmyElementextendsHTMLElement{constructor(){super();this.attachShadow({mode:"open"});}//Utilizaremos un observer, esto estara observando nuestros atributos//Es como indicarle al componente cuales son los atributos tendra//Si hay algo en otro que no esta en esta lista no es de el componentestaticgetobservedAttributes(){//Aqui le decimos al observador que atributos tendra nuestro componente//Si hay otro atributo que no este aqui este no sera de importanciareturn['title','parrafo','img']}//Ya teniendo los atributos que seran observados podremos utilizar el//attributeChangedCallback//Esta funcion recibe tres parametro// 1. valor actual// 2. valor viejo// 3. nuevo valorattributeChangedCallback(attr, oldVal, newVal){//Aqui vamos a generar los cambios de acuerdo a lo que existe en los atributos//aqui hacemos una validacion para verificar si existe el atributo en nuestro componenteif(attr ==="title"){//le asignamos a la variable title que obtenemos desde el observador de//nuestro componente un nuevo valor //Esto quiere decir que si hay un nuvelo valor se tiene que hacer el cambio de //Forma dinamicathis.title= newVal;}if(attr ==="parrafo"){this.parrafo= newVal;}if(attr ==="img"){this.img= newVal;}}getTemplate(){const template =document.createElement('template'); template.innerHTML=`<section><h3>${this.title}</h3><div><p>${this.parrafo}</p><imgsrc="${this.img}"></div></section>${this.getStyles()}`;return template
}getStyles(){return` <style>
h2{
color:red;
}
</style>
`}render(){this.shadowRoot.appendChild(this.getTemplate().content.cloneNode(true))}connectedCallback(){this.render();}}customElements.define('my-element', myElement);
Creo que hubo un error de edicion o algo en la clase, no se demuestra que los valores de los atributos cambien en tiempo real.
.
Para lograrlo agregué la siguiente logica, por si a alguien le ayuda:
Se me ocurrió esto para cuando tengas muchos parámetros no tener que hacer muchos ifs y solo actualizar el valor del attr si ha cambiado
Para estos casos y por buena práctica es recomendable que el resultado de un if ternario siempre se asigne a una variable por ejmplo lo que tiene puede quedar asi
Como podemos ver, al cambiar atributos no se renderizan los cambios, es por eso que he decidido hacer un pequeño cambio en el metodo render() para utilizarlo también en el attributeChangedCallback()
Esta solución me agrado más, pero podrías hacer esto
attributeChangedCallback(attr, oldVal, newVal){if(oldVal !== newVal){this[attr]= newVal;// valida que el componente este montado para que solo // renderize cuando realmente exista un cambio en las propiuedades// ya que al dejarlo asi estas renderizando el componente por cada // propiedad this.shadowRoot.children[0] = al componente que estas creando// de esta manera solo renderizara cada vez que cambies una atributoif(this.shadowRoot.children[0]){this.render();}}}render(){this.shadowRoot.innerHTML='';this.shadowRoot.append(this.getTemplate().content.cloneNode(true));}
Cuando agregamos el metodo “observedAttributes” y retornamos title como parte del arreglo, reacciona para todos los attributos title del DOM, como se puede corregir para que solo sean los suyos?
Porque retorna un error "Uncaught RangeError: Maximum call stack size exceeded"
x2
¿porque ocurre un error en el callstack por exceso de tareas, al momento de utilizar el observador y el attributeChanged?
Porque JS es mono hilo.
si pero eso en que me ayuda o aporta lo que necesito es solucionar el error y saber porque sucede especificamente
No se si os pasará a vosotros tambíen pero yo he tenido que añadir una comprobación adicional en attributeChangedCallback ya que sino me hacia un bucle infinito al intentar cambiar el attributo por javascript.
De echo, cuando se renderiza el componente y se le asigna el attributo, se llama a la función attributeChangedCallback y ésta entra en un bucle infinito.
Les comparto mis notas de la clase, espero les sirva y puedan entender mejor el código.
Perdón por la calidad de la imagen.
¿para que declaramos oldValue si nunca se usa?
Los cambios en el navegador se producen solo una vez en el constructor, luego no vuelve a dibujarse el nodo con los cambios
No entiendo para que esto si cuando se cambia el valor del atributo en html sin el attributeChangedCallback igual cambia
Hola, Sebastián :)
Puede haber muchos escenarios donde estés cambiando el atributo de algún elemento html y quieras ejecutar una función (callback) de inmediato.
Por ejemplo, al mover el cursor del mouse quieras actualizar atributos con base en las coordenadas y después ejecutar una función para evaluar la posición del elemento :thinking:
En conclusión, no es necesario el callback para que funcione, pero es un muy útil tener la posibilidad cuando tu código lo necesita :D.
ah, ya entendi, jajaajja si esa era la duda y pense que era algo innecesario pero veo la intencion de que siempre se este analizando si los atributos cambian
No entiendo la diferencia entre el método usado en esta clase y el anterior. En ambos requiero guardar las modificaciones en el index.html para verlas reflejadas en la pagina.
En verdad no logro ver el cambio, le indico los 3 valores, pero solo encuentra 1 , alguien puede decirme o apoyarme