Componentes web: cómo crear elementos HTML personalizados | Christopher Dodd | Skillshare
Menú
Buscar

Velocidad de reproducción


  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

Componentes web: cómo crear elementos HTML personalizados

teacher avatar Christopher Dodd, Web Developer / Educator

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Lecciones en esta clase

    • 1.

      Introducción

      0:53

    • 2.

      Componentes web - un ejemplo de vida real

      1:36

    • 3.

      Las 4 especificaciones de componentes web

      4:07

    • 4.

      Elementos personalizados Parte 1

      17:17

    • 5.

      Elementos personalizados

      14:16

    • 6.

      La sombra

      15:20

    • 7.

      Ranuras y plantillas

      12:10

    • 8.

      Elementos incorporados personalizados

      9:22

    • 9.

      Módulos ES

      8:00

    • 10.

      Componentes web en práctica

      29:20

    • 11.

      Componentes web en práctica

      14:59

    • 12.

      Componentes web en práctica

      22:36

    • 13.

      Conclusión

      0:30

  • --
  • Nivel principiante
  • Nivel intermedio
  • Nivel avanzado
  • Todos los niveles

Generado por la comunidad

El nivel se determina según la opinión de la mayoría de los estudiantes que han dejado reseñas en esta clase. La recomendación del profesor o de la profesora se muestra hasta que se recopilen al menos 5 reseñas de estudiantes.

392

Estudiantes

--

Proyecto

Acerca de esta clase

En la clase de hoy, vamos a aprender sobre el conjunto de 4 especificaciones que conforman la meta-specification de componentes web y cómo podemos usar para crear nuevas etiquetas HTML personalizadas y reutilizables para usar en páginas web y aplicaciones web.

Para aquellos que tienen experiencia en codificación con Javascript, aprender a crear elementos personalizados para tus aplicaciones web y sitios web puede ser una herramienta útil para encapsular funcionalidad y reutilizarlo en cualquier lugar de un proyecto particular o en varios proyectos.

Conoce a tu profesor(a)

Teacher Profile Image

Christopher Dodd

Web Developer / Educator

Top Teacher

Christopher Dodd is a self-taught web developer, YouTuber and blogger with a mission to help individuals learn the skills to freelance and make a living independently.

Chris learned web development in 2015 in order to work remotely and travel the world and has done so for the past 2 years.

Through his YouTube channel, blog and Instagram, Chris inspires and educates newbie 'digital nomads' to chase their passions and pursue a location independent career.

Ver perfil completo

Level: Advanced

Valoración de la clase

¿Se cumplieron las expectativas?
    ¡Superadas!
  • 0%
  • 0%
  • Un poco
  • 0%
  • No realmente
  • 0%

¿Por qué unirse a Skillshare?

Mira las galardonadas Skillshare Originals

Cada clase tiene lecciones cortas y proyectos prácticos

Tu membresía apoya a los profesores de Skillshare

Aprende desde cualquier lugar

Ve clases sobre la marcha con la aplicación de Skillshare. Progresa en línea o descarga las clases para verlas en el avión, el metro o donde sea que aprendas mejor.

Transcripciones

1. Introducción: Hola y bienvenidos a esta clase sobre componentes web, tu guía para crear elementos HTML personalizados con JavaScript. Soy Christopher Dodd. Soy desarrollador web freelance y principal profesor aquí en SkillShare.com, cubriendo todas las cosas desarrollo web y trabajo independiente en línea. En la clase de hoy, vamos a aprender sobre el conjunto de cuatro especificaciones que conforman los componentes web, meta especificación, y cómo podemos usarlas para crear nuevas etiquetas HTML personalizadas y reutilizables para uso en páginas web y aplicaciones web. Para aquellos de ustedes que tienen experiencia codificando con JavaScript, aprender a hacer elementos personalizados para sus aplicaciones web y sitios web puede ser una herramienta útil para encapsular funcionalidad, y lo estamos usando en cualquier lugar dentro de un proyecto en particular o a través de múltiples proyectos. Si estás listo para aprender a crear tus propios elementos HTML personalizados con JavaScript, haz clic en el siguiente video y te veo por dentro. 2. Componentes web: un ejemplo de vida real: Web Components fue algo que surgió en mi radar dado mi trabajo con sitios de comercio electrónico impulsados por Shopify. Fue junio de 2021 cuando Shopify reveló que su tema predeterminado había sido actualizado para encapsular la mayoría de la lógica JavaScript en alrededor de 20 componentes web diferentes, como modales, cantidad, entradas, y más. Incluso crearon su propio componente deslizador que no requiere bibliotecas JavaScript externas. Si bien no he podido encontrar ninguna declaración de Shopify en cuanto a por qué eligieron crear sus nuevos temas de tienda online 2.0 como este, confío en que si los componentes web era como Shopify, una empresa tecnológica de varios mil millones de dólares quiso estructurar la lógica de sus temas desarrollados internamente, entonces esta fue una especificación para tomar nota y aprender más sobre. un sitio de comercio electrónico como puede esperar queun sitio de comercio electrónico como los que normalmente se alojan en Shopify tenga alguna funcionalidad común que se puede encapsular a través de componentes web. Para usar como ejemplo el tema Dawn de Shopify, los principales puntos de interactividad como la tabla de artículos en la página del carrito, las opciones para filtrar productos dentro de una colección, y el formulario de producto, son todas las áreas donde la funcionalidad se puede liar en componentes web separados. Al final de esta clase, vamos a tomar ejemplo de Shopify como inspiración para construir nuestra propia funcionalidad de carrito de compras que consta de tres componentes separados, todos los cuales interactuarán con el uno al otro. Pero antes de llegar allí, necesitamos obtener una comprensión más profunda de la teoría detrás de los componentes web. Empezando con una visión general de las cuatro especificaciones de componentes web. 3. Las 4 especificaciones de los componentes web: Para esta lección particular, me voy a referir al sitio web dedicado a ayudar a los desarrolladores a compartir, descubrir y reutilizar componentes web, web components.org. Entonces, si alguna vez estás perdido en algún momento sobre la siguiente teoría, simplemente puedes volver a chequear en web components.org/specifications para seguir adelante. Tal y como está escrito aquí en web components.org, los componentes web es una meta-especificación hecha posible por otras cuatro especificaciones. La especificación de elementos personalizados, la especificación shadow DOM, la especificación de plantilla HTML y la especificación del módulo ES. En esta lección, cubriremos brevemente todas estas especificaciones desde un punto de vista teórico y en los próximos videos, veremos cada especificación en la práctica. Empecemos con elementos personalizados. La especificación de elementos personalizados es la especificación fundacional que hace posible los componentes web. Utilizando este método define en el objeto de elementos personalizados, podemos definir un nuevo elemento personalizado. El primer argumento es el nombre del elemento personalizado, que es lo que usamos para llamarlo dentro del HTML. El segundo parámetro es el constructor, que es donde irá toda la lógica. Podemos crear esta clase construida extendiendo la clase de elemento HTML o una clase de elemento HTML nativa existente como en el ejemplo aquí, pero llegaremos a eso un poco más tarde. La mayoría de las veces estarás extendiendo la clase de elemento HTML normal para crear tus componentes. A esto se le llama un elemento personalizado anónimo. Aquí tenemos acceso al componente tal como existe en el DOM a través de lo poderoso, esta palabra clave. Cada vez que usamos el elemento personalizado en nuestro HTML, se crea una instancia y luego podemos escribir código dentro esta declaración de clase relacionada específicamente con la instancia particular del componente. La siguiente especificación es la sombra DOM, que le permite crear un DOM separado al DOM regular. Por lo tanto, el DOM regular es referido a veces como el DOM de luz para distinguirlo al hablar de la alternativa, que es el DOM sombra. La API de sombra DOM le permite adjuntar un subárbol DOM a elementos dentro de su documento web. El DOM de sombra adjunta está encapsulado, lo que significa que la información de estilo en su interior no puede aplicarse a elementos externos y viceversa. Podemos adjuntar el DOM de sombra a cualquier elemento a través del método de sombra adjunta. Pero en el contexto de la construcción de componentes web, el DOM de sombra se crea típicamente directamente en el propio componente web usando esto.AttachShadow. Usando este objeto raíz de sombra, podemos construir un subárbol de elementos, todos los cuales son virtualmente invisibles a la luz principal DOM. A continuación, hablemos de la especificación de plantilla HTML. Esta es simplemente una forma de crear una estructura HTML que no se renderizará en su lugar como HTML normal. Creamos una plantilla a través de la etiqueta de plantilla, colocamos nuestro HTML dentro y cuando la página se carga, el HTML no se renderizará, pero sigue siendo accesible a través de JavaScript. Como su nombre indica, podemos usar estas etiquetas para crear código de plantilla que se puede clonar y usar en múltiples ubicaciones. En el contexto de construir un componente web, la etiqueta de plantilla se puede utilizar para definir el HTML del componente clonando el HTML desde dentro de las etiquetas y colocándolo bien directamente en el HTML interno de el componente o en su sombra DOM. Por último, la especificación del módulo ES define la inclusión y uso de documentos JS en otros documentos de JS. Si bien no es esencial para construir componentes web, almacenar sus componentes web como código modular que existe dentro su propio archivo JS puede ser útil para la estructuración de proyectos, especialmente al traer a terceros componentes web. La sintaxis para la especificación es importar su script externo como de costumbre, excepto esta vez que establece el módulo como el parámetro type. Después se escribe entrada seguida de la ruta al archivo. Las capacidades de la especificación de elementos personalizados, la especificación shadow DOM, la especificación de plantilla HTML y la especificación del módulo ES funcionan muy bien juntos para ayudarnos a escribir limpio, elementos HTML personalizados encapsulados y reutilizables. Teóricamente, es sólo la especificación de elementos personalizados que se requiere para crear elementos personalizados, pero como verá en videos posteriores, combinar capacidades de cada especificación es a menudo la mejor manera de sacar el máximo provecho de los componentes web. 4. Elementos personalizados, parte 1: Ahora que hemos cubierto las cuatro especificaciones de componentes web en el último video, veamos cada una de estas en profundidad y en acción dentro de nuestro editor de código. Lo que voy a hacer es iniciar un proyecto completamente nuevo. Tengo una carpeta aquí para mi código. Voy a crear una nueva carpeta de proyecto y la voy a llamar componentes web. Puedes llamarlo como quieras. Entonces voy a arrastrar esto a mi editor de código, que es Visual Studio Code, y esto abrirá automáticamente esa carpeta para nosotros. Entonces voy a cerrar esto hacia abajo, haga clic en nuevo archivo por aquí, y crear un archivo HTML. Lo vamos a llamar index.html. Ahora usando Emmet dentro de Visual Studio Code, puedo emitir algún HTML calderín escribiendo signo de exclamación y luego golpeando “Enter”. Voy a cambiar el título aquí solo a componentes web. Entonces voy a crear el archivo JavaScript, voy a llamar component.js porque vamos a estar trabajando con un solo componente primero hacia arriba. Voy a hacer el clásico hola mundo para nuestra consola. Regresar a aquí y luego modificación final que necesito hacer para que esto comience es realmente vincular ese archivo JavaScript. Ahí vamos. Ahora lo que voy a hacer es volver a nuestra carpeta y abrirla en Google Chrome. Es Google Chrome para mí, pero puedes usar cualquier navegador que te guste. Voy a usar la opción de comando I para abrir aquí mis herramientas de desarrollador, y si voy a la consola, solo voy a hacer esto más grande para ustedes chicos, se puede ver hola mundo, que nos muestra que estamos enlazando correctamente ese archivo JavaScript que creamos aquí. Impresionante. Ahora que eso está hecho, vamos a crear en realidad nuestro primer componente web. De nuevo, hay algo de calderas a esto. Todo lo que tenemos que hacer, y esto va a ser lo mismo para cada componente web, aparte de los incorporados personalizados que veremos más adelante, solo voy a llamar a este componente web y como se puede ver aquí, la primera letra de cada una de las palabras en este nombre de clase aquí están en mayúscula. Esa es la convención que usamos. Después escribimos extiende y luego elementos HTML. Entonces aquí necesitamos un constructor. Entonces llamamos a la super función, que vamos a llamar cada vez que hagamos un componente web y básicamente lo que esto hace es hereda las funciones constructivas de la clase que es extendiendo. Necesitamos eso para aprovechar lo que estamos extendiendo aquí mismo. Entonces vamos a bajar aquí y terminar esto corriendo el método define en elementos personalizados. El primer parámetro va a ser cómo va a verse el nombre del elemento en nuestro documento HTML y luego el segundo argumento es el nombre de clase que acabamos de crear aquí. Ahí lo tenemos, nuestro primer componente web. Ahora con el fin de llevar eso nuestro front-end y ejecutarlo en nuestro HTML, acabamos de tener esta etiqueta personalizada disponible para nosotros, componente web. Eso por supuesto es igual a lo que dijimos aquí en este método de definición. A lo mejor voy a correr estos uno al lado del otro. Aquí vamos. Por último, para que podamos verificar que este componente web se está construyendo y ejecutando en la página, voy a poner un inicio de sesión de consola aquí y simplemente escribir hola mundo de nuevo. Volvamos a nuestro documento HTML, refrescamos la página y se puede ver el hola mundo es el registro de consola. Si miramos en nuestra página aquí, se puede ver eso es porque hemos llamado a ese elemento personalizado. Ahora hasta ahora eso no parece ser ningún uso práctico de usar esto pero a medida que avanzamos a lo largo de este curso, comenzarás a ver cómo los componentes web encapsulan cierta funcionalidad a elementos específicos aquí . Una de las formas en que podemos ver que es mediante el uso de la, esta palabra clave. Si acabo de escribir esto en un registro HTML y consola que, entonces somos capaces de hacer referencia a lo que pongamos entre estas etiquetas. Pondré ahí el mundo hola. Volvamos por aquí, refresco. Se puede ver que tenemos algún contenido entre esas etiquetas de componentes web y luego eso se hace eco aquí en nuestra consola también. Eso solo te va a mostrar que podemos tomar el propio componente web como referencia usando esto y luego hacer cosas dentro de este componente, que vamos a empezar a ver muy pronto. Ese es nuestro componente web básico. A continuación, déjame mostrarte cómo podemos crear HTML interno dentro de nuestro componente web. Voy a hacer esto dentro del método constructor porque esto se ejecuta cada vez que se construye el componente. Escribiré algunos comentarios aquí. El primer método es simplemente estableciendo el HTML interno. Voy a anotar eso. Podemos ir este HTML interno igual que lo hicimos antes y en lugar de salirlo, podemos anularlo. Voy a usar las garrapatas atrás aquí así que no tengo ningún problema con comillas, ya sea comillas dobles o citas simples. Lo que voy a hacer es crear un div y dentro del div crear un span y luego en el lapso voy a decir, este es un componente web. Nuevamente, si actualizo por aquí y luego voy e inspecciono este elemento, se puede ver que hemos insertado este HTML dentro del componente web. El segundo modo en que podemos hacerlo es creando elementos y agregándolos al DOM. Te mostraré cómo lo hacemos ahora mismo. Vamos a comentar esto y te mostraré aquí la segunda opción. Vamos a pasar esto para que podamos ver más de ello. Quizá aumente el tamaño de la pantalla. Ahí vamos. Entonces lo que voy a hacer es usar documento crea elemento y literalmente podemos poner en el nombre del elemento aquí para crear un elemento. Pero tenemos que guardarlo en alguna parte, así que voy a poner un const div al frente. Eso almacenará el elemento div recién creado en esta constante div. Entonces voy a crear el lapso que teníamos antes. Estoy creando exactamente lo mismo que aquí arriba. Documento crea tramo de elemento. Entonces ahora tenemos nuestro div y nuestro lapso. Antes de adjuntar el div a nuestro documento, voy a actualizar el HTML interno del lapso a lo que teníamos antes, este es un componente web. Entonces lo que puedo hacer es usar estos métodos child append para construir básicamente el DOM. Puedo anidar el lapso dentro del div, y luego puedo anidar el div dentro del propio componente web, así. Ahora si vuelvo por aquí, tenemos un poco de un tema. Ese tema es que ponemos contenido aquí. Sólo voy a quitar eso, salvo eso. Si nos dirigimos hacia atrás, ahí vas, vamos a conseguir div con el palmo dentro. Esa es otra forma de hacerlo. La forma final de hacerlo es analizar una cadena HTML. Voy a comentar eso y luego escribiré el tercer comentario, analizaré una cadena HTML. Digamos por ejemplo, en una situación particular tenía una cadena HTML, y quería poner la cadena HTML como HTML dentro de este componente web. Sólo hagamos eso otra vez. Lo mismo otra vez, div con un span dentro, este es un componente web, cierra el span, cierra el div. Entonces lo que necesito hacer porque esta es una cadena, necesito analizarla. La forma en que puedo analizarlo es mediante el uso del analizador DOM. Veamos eso ahora mismo. Puedo establecer const HTML interno en nuevo analizador DOM, y luego ejecutar el parse desde el método string, que tomará la cadena HTML como su primer argumento. Entonces el formato Texto/HTML. Entonces lo que eso va a hacer, es que me va a dar este DOM analizado. Lo que necesito hacer es realmente encontrar el cuerpo y luego sacar el HTML interno de eso. Básicamente estoy creando un nuevo DOM con esta cadena HTML y luego estoy sacando el HTML interno del cuerpo de ese nuevo DOM. Entonces lo que simplemente puedo hacer es decir que este HTML interno es igual a HTML interno. Siendo este el componente web, estoy configurando el HTML del componente web el HTML interno de esta cadena HTML analizada. Todo parece bueno. Refresca aquí y obtenemos exactamente el mismo resultado. Ahora, no te va a quedar inmediatamente claro por qué necesitarías usar tres métodos diferentes o qué método usar. Usa cualquier método que funcione para ti, si este es el más fácil y puedes salirte con la suya, definitivamente usa ese. Pero hay ciertas situaciones en las que tal vez estés obteniendo HTML devuelto de una API, que es el caso en los temas de Shopify, entonces necesitas usar este método de analizador DOM, o tal vez está obteniendo un un poco complicado con la creación nuevos elementos que se encajan en una estructura HTML más compleja, en cuyo caso, es posible que desee utilizar este método. En este sencillo ejemplo, parecería que esta es la forma más fácil de hacerlo, que es. Pero a medida que los ejemplos se vuelven más complejos, es posible que empieces a necesitar usar una combinación de esto o esto. Lo que quería hacer en esta pequeña sección era mostrarte cómo puedes hacer eso. Lo siguiente que quiero mostrarte son atributos personalizados. Voy a deshacerme de todo esto. No te preocupes, todo esto estará en el enlace de GitHub, para que puedas mirar este código cuando quieras. Lo que quiero mostrarte ahora es que en realidad podemos crear nuestros propios atributos personalizados. Aquí en esta etiqueta de componente web, podría escribir algo como texto o cualquier parámetro que quisiera poner a través. Digamos que esto es un componente web. Tengo un parámetro por el nombre del texto y estoy analizando eso como un valor. ¿ Cómo usamos eso? Bueno, voy a cerrar esto. Lo que voy a hacer es acceder a ese atributo vía this.getAttribute. Entonces el argumento para eso es el propio nombre del atributo, que es texto. Solo consigamos que consigamos eso para empezar. Entonces encontraremos un uso más práctico de la misma. Refrescante por aquí, si entro a la consola, se puede ver que esto es un componente web, y eso coincide con el parámetro que establecí por aquí. Eso no es muy útil hasta ahora. Lo que voy a hacer es el número 1, voy a poner esto en una variable. Voy a crear una variable dentro de este componente, así que adjuntándola a esto. Voy a llamarlo contenido de texto interno. Pero antes de hacer eso, quiero comprobar si este elemento realmente tiene ese atributo. Voy a usar el método de atributo has analizando a través del texto como nombre del atributo. Entonces voy a poner eso en el bloque if ahí. Nuevamente, esto debería funcionar. Aquí no hay errores, hay registro de consola, pero eso es porque aún no hemos registrado nada de la consola ni hemos cambiado nada. Lo que podría hacer aquí es igual que antes, usa el método que teníamos antes este sencillo método de simplemente configurar el HTML interno. Lo que voy a hacer es usar esa misma estructura de nuevo con el div y el lapso anidado. Pero en el lapso anidado, voy a poner un valor dinámico basado en ese atributo. Porque establecemos esta variable aquí mismo, lo que voy a hacer es poner eso aquí esto.InnerTextContent. Entonces refrescar por aquí. Se puede ver que tenemos el mismo resultado que el que teníamos antes. Volvamos a nuestro HTML. Si iba a cambiar esto a, este es un componente. Eso es lo que se envía a través al lapso. Ahora el único tema con esto es si volvemos aquí y digamos que tenemos un componente web bastante dinámico aquí un componente web bastante dinámicodonde este valor va a cambiar. Si cambio esto a, este es un componente web, de nuevo, simplemente no un componente.Verás que nada se actualiza. Eso es porque en realidad tenemos que observar los cambios en los atributos, para que esto cambie realmente. De vuelta al archivo component.js, vamos a hablar más sobre métodos del ciclo de vida en la siguiente sección. Pero por ahora, lo que voy a hacer es mostrarte el método de ciclo de vida que podemos usar para comprobar si hay cambio de atributo. Aquí, nuestro atributo correcto cambió la devolución de llamada, y toma tres argumentos. El primero es el propio nombre del atributo. Voy a decir nombre attr. El segundo atributo es el valor antiguo, y el tercer atributo es el nuevo valor, el valor al que se va a cambiar. Entonces voy a ponerlo en un cheque aquí. Si el nombre atrr es texto, entonces vamos a actualizar el HTML interno. Mantén esta estructura. En lugar de este contenido de texto interno, vamos a establecer eso al nuevo valor que viene a través de la devolución de llamada. Eso podría parecer el último paso, pero hay un paso más que tenemos que hacer, que es decirle al componente web que cuide este atributo en particular. Esta es solo una forma de los componentes web sean más delgados y se aseguren que no estén revisando atributos que no importan al programador. Lo que tenemos que hacer para eso es simplemente escribir static, obtener atributos observados. Entonces solo vamos a devolver una matriz con todos los atributos que queremos ver, que es sólo texto. Vamos a ir a nuestro navegador aquí, refrescar. Tenemos un error de sintaxis. Eso es porque necesito poner esto fuera del constructor. Este es el método constructor aquí mismo. Necesito poner eso afuera, refrescar por aquí. Esto debería funcionar. No hay errores. Si entro aquí y cambio, este es un componente a esto es un componente web o cualquier otra cosa, se puede ver que el HTML interno ha cambiado. Hemos ejecutado con éxito este método aquí porque estamos comprobando cualquier atributo observado con el nombre del texto. Comprobamos si el nombre del atributo que viene a través de esta devolución de llamada es texto, y si es así, actualizamos el HTML interno a esta nueva estructura HTML con el nuevo valor. Ya hemos cubierto mucho que ver con la especificación de elementos personalizados. Voy a romper la segunda mitad de este video en una parte 2. En la siguiente parte, vamos a ver los métodos del ciclo de vida y los eventos personalizados. 5. Elementos personalizados pt 2: En este video de la Parte 2, discutiendo las características de la especificación de elementos personalizados, vamos a hablar de métodos del ciclo de vida y elementos personalizados. En el último video, en realidad vimos uno de estos métodos del ciclo de vida, la devolución de llamada de cambio de atributo. Voy a poner esto como el número 3, que hablaremos en tan solo un segundo. Un poco de descargo de responsabilidad aquí, voy a considerar el constructor número 1 aquí a pesar de que técnicamente no es un método de ciclo de vida, pero ayuda a mirar constructor en el contexto de la vida- métodos de ciclo de todos modos. Aquí hay una segunda, que voy a revelar muy pronto, y una cuarta, que voy a revelar aquí. Hablemos primero del constructor. El constructor, escribiré algunos aquí y pondré esto en el GitHub para ustedes para que puedan referirse a él más tarde. Déjame arreglar este errata. Esto se ejecuta cuando el componente se crea en memoria, pero no necesariamente unido al DOM todavía. Según mi investigación, este es el mejor lugar para la inicialización, pero no el mejor lugar para interactuar con el DOM. Ahora, la diferencia entre constructor y el siguiente es bastante sutil. Pero si alguna vez tienes problemas con poner algo en esta función constructor y no funciona, la siguiente es probablemente donde necesites ponerlo, y esa es la devolución de llamada conectada. Escribiré eso aquí, devolución de llamada conectada. Eso se ejecuta cuando el elemento está realmente unido al DOM. Se ve exactamente así, devolución de llamada conectada. Este tercero, como vimos antes, atributo cambiado callback es simplemente verificando si un atributo ha cambiado. Bastante simple de entender. Esta cuarta que vamos a mirar es la devolución de llamada desconectada, que es todo lo contrario a la devolución de llamada conectada. Esto se ejecuta cuando el elemento se desprende del DOM. Se podría pensar, bueno, ¿por qué necesitamos eso? Es útil para realizar la limpieza, por lo que procesos que ya no queremos ejecutar una vez que nos deshacemos de ella. Se ve exactamente como la devolución de llamada conectada excepto que es devuelta de llamada desconectada. Hay uno o dos más, pero estos son los principales. Hemos visto constructor, hemos visto el cambio de atributo callback. Los dos que aún no hemos mirado hasta que este video estén conectados y desconectados. Lo que voy a hacer aquí es poner algunos registros de consola y luego puedo mostrarte cómo se ve cuando se ejecuta la devolución de llamada conectada y se ejecuta la devolución de llamada desconectada. Todo lo que voy a hacer es decir callback conectado, y luego escribir aquí, callback desconectado. Si ejecuto este código ahora, si entro a mi consola, actualiza la página, puedes ver que se ejecuta la devolución de llamada conectada. Si pongo en un registro de consola aquí, y digamos constructor, y luego pasamos por aquí, se puede ver constructor y se ejecuta la devolución de llamada conectada. Aquí es donde ocurre la sutil diferencia entre constructor y callback conectado. La devolución de llamada conectada es técnicamente cuando el elemento está unido al DOM y constructor es cuando se crea en la memoria. Pero los dos están sucediendo automáticamente una vez que ponemos este componente en nuestro documento. ¿ Cómo puedo demostrarte la diferencia entre callback conectado y constructor? Bueno, una de las formas en que puedo mostrarte esto es mediante eliminación programática este componente web del DOM, aún teniendo en una memoria y luego reconectándolo. Eso es lo que voy a hacer en este ejemplo aquí mismo. Justo por encima de la etiqueta de script JS componente, voy a crear otra etiqueta de script. Lo que voy a hacer es agarrar el propio componente web. Voy a crear un componente web variable, y luego vamos a usar selector de consultas de documentos para agarrar el elemento componente web. Al igual que lo haríamos con cualquier otro elemento, podemos hacer esto con nuestros propios elementos personalizados también. Entonces lo que voy a hacer es simplemente basar esto en el tiempo de espera para los efectos de este ejemplo. Voy a crear esta función de tiempo de espera. Vamos a ejecutarlo después de un segundo. Entonces dentro de la función timeout, lo que voy a hacer es eliminar child en el cuerpo del documento y eliminar ese HTML del componente web del cuerpo del documento, sólo para volver a adjuntarlo. DocumentBody.append componente web hijo. Básicamente, todo esto está haciendo es después de que se cargue un segundo de esta página, vamos a quitar ese componente web del cuerpo en el que está actualmente encendido y ponerlo de nuevo en el cuerpo. Refresquemos por aquí y esperemos un segundo. Se puede ver que la función constructor se ejecuta una vez porque el componente web se crea una vez en la memoria. Entonces, por supuesto, la devolución de llamada conectada ocurre casi simultáneamente con el constructor. Pero entonces lo que vemos después de un segundo, si vuelvo a ejecutar esto, después de un segundo, que es el parámetro que ponemos aquí para el tiempo de espera, verás que la devolución de llamada desconectada se ejecuta porque estamos eliminando un componente web del DOM y luego lo estamos devolviendo a poner para que la devolución de llamada conectada se ejecute de nuevo. Aquí se puede ver la sutil diferencia entre constructor siendo creado la memoria y la interacción del componente web con el DOM. A menudo sucede al mismo tiempo. Pero si tuviéramos que tomar el componente web y moverlo alrededor de nuestro DOM, entonces la devolución de llamada conectada y la devolución de llamada desconectada son útiles. Hemos demostrado dos en uno allí. Pero si volvemos aquí y en realidad voy dentro de la sección de elementos de mis herramientas dev aquí, haga clic en el componente web. En realidad, aclaremos todo esto. Haga clic en este elemento ahora y elimínelo de nuestro DOM. Si voy a la pestaña de la consola, se puede ver que la devolución de llamada desconectada se ha vuelto a ejecutar. Eso es básicamente llamada conectada y devolución de llamada desconectada. Simplemente se ejecuta cuando el elemento está unido al DOM y cuando el elemento se desprende del DOM. Veremos cómo necesitamos usar devolución de llamada conectada en un ejemplo una vez que lleguemos a los componentes web en la práctica más adelante en esta clase, pero por ahora, hasta que tengas un problema donde tiene que usar la devolución de llamada conectada, probablemente solo pueda usar constructor para todas sus inicializaciones y todo lo que desea ejecutar cuando se crea este componente web. Una vez que empiezas a tener problemas sin embargo con código de ejecución dentro de su constructor, es entonces cuando necesita comenzar a mirar la función de devolución de llamada conectada. Eso son métodos de ciclo de vida. Por último, en esta especificación de elementos personalizados, quiero hablar de eventos personalizados. Lo que voy a hacer es borrar parte de este código. Voy a deshacerme de este set Timeout. Todavía voy a mantener mi componente web en esta constante aquí. Golpea, “Ahorra” en eso, dirígete por aquí. Lo que voy a hacer es actualizar este HTML aquí. Voy a tener que hacerlo dos veces porque tenemos esto por aquí también. Sólo voy a crear un botón. En este botón, solo voy a poner el evento especial desencadenador de contenido. Voy a copiar ese código hasta aquí. Cuando cambia el atributo, lo que en realidad sucede en la primera vez que el atributo se establece de todos modos. Si no hacemos esto, si dejo esto apagado y ejecuto la página, verás que el botón no aparece todos modos porque el cambio de atributo, devolución de llamada se ejecuta tan pronto como reconozca ese atributo. Este no es el código más limpio pero vamos a copiar y pegar eso por aquí. Ahora si miro aquí mi componente y hago clic en este botón, vamos a conseguir que haga algo muy pronto. Deshaznos de estos registros de consola. Ya no los necesitamos. Podemos mantener ahí esta devolución de llamada conectada. Voy a deshacerme de estos comentarios aquí, los que voy a dejar en la rama correspondiente del GitHub para que puedas referenciar eso más adelante. ahora me voy a deshacer de esos comentarios. Entonces lo que voy a hacer es crear nuestro propio evento personalizado. Voy a crear un método que se va a ejecutar en nuestro EventListener, así que desencadenar evento especial. Con el fin de crear nuestro propio evento personalizado, solo podemos asignar nuevo evento. En el parámetro aquí, podemos llamar al evento donde queramos. Sólo voy a llamarlo Especial. Ahora ese nuevo evento, ese evento especial se almacena en esta constante de evento especial. Cuando se ejecuta este método, lo que podemos hacer es que podamos despachar ese evento ejecutando el evento de despacho. Entonces aquí corriendo evento especial. Entonces lo que vamos a hacer aquí arriba es ir a nuestra devolución de llamada conectada y agregar un oyente de eventos al evento click en el botón para ejecutar este evento especial. Voy a encontrar el botón dentro de este componente web, que podemos hacer a través de este selector de consultas. Agregar EventListener, busque el evento click. Entonces podemos ejecutar este evento especial disparador. Entonces vamos a vincular esto, por lo tanto, permitiéndonos hacer referencia a esto como el componente web. Si el método bind te confunde un poco, no te preocupes. Me confundió por un tiempo también. Todo lo que hace es asegurarse de que esta palabra clave dentro de la función esté relacionada con esto, el componente web, no esto la función o cualquier otra cosa. Es sólo un paso extra. Si no lo usamos terminaremos con este ser no lo que pretendíamos que sea. Ahora, lo que va a pasar es que cuando hacemos click en el botón, vamos a desencadenar este evento especial que desplaza nuestro propio evento personalizado, que se llama evento especial. Pero si hago clic en el botón, realmente no pasa nada. Técnicamente, este evento especial se desencadena pero en realidad no estamos escuchando para ese evento especial. Nada realmente se actualiza en la página. Vamos a cambiar eso. Vamos a entrar en nuestro archivo HTML aquí. Debajo aquí en nuestra etiqueta de script, voy a agregar ese EventListener en nuestro componente web. Ya hemos almacenado nuestro componente web aquí en esta constante, por lo que puedo hacer componente web, agregar EventListener. Literalmente podemos escuchar el evento especial que creamos, para que podamos poner en especial. Entonces vamos a poner en esta función anónima que simplemente se registre la consola. El evento especial ha sido desencadenado. Aquí tenemos tres pasos. Hemos creado un método de evento especial el cual despacha un evento personalizado que llamamos especial. Hemos adjuntado eso al click EventListener en el botón. Entonces vamos a escuchar ese evento especial en el propio componente web y el registro de consola, el evento especial se ha disparado si ese evento ha sido despachado. Si volvemos a nuestro documento aquí y hago clic, “Desencadenar evento especial”, se puede ver que se va a ejecutar, se ha disparado el evento especial. Si hago clic en eso, se puede ver que el número sube aquí. Obviamente, este sencillo ejemplo no comunica realmente la necesidad de un evento personalizado. Pero cuando empiezas a tener elementos más complejos puede ser que quieras tener un botón que desencadena el evento especial. Quieres tener algo más que desencadena el evento especial. Simplemente tiene sentido semánticamente tener un evento especial en su componente web, entonces esto viene muy bien. Un ejemplo que podrías encontrar en el mundo real es Modals. Es posible que tengas un evento cerrado en un componente web modal. Ese evento cerrado podría activarse desde un clic de botón o haciendo clic fuera del modal o haciendo clic en Cancelar. Tienes tres eventos separados diferentes que quieres desencadenar el mismo evento en el propio componente web. A continuación, puede comprobar fuera de su componente web si se el evento cerrado en ha ejecutadoel evento cerrado en ese componente web modal. Ese es un ejemplo que he visto en el mundo real por usar elementos personalizados. Pero de nuevo, lo he hecho realmente sencillo en este video, sencillo posible para que ustedes lo vean en acción. Nuevamente, si no sientes la necesidad de usar esta función, no tienes que usarla. Pero si lo ves en el mundo real y estás tratando de entender lo que está pasando cuando ves algo como esto, bueno, esta es la explicación. Podemos crear eventos personalizados que podamos enviar en nuestro componente web. Eso nos permite buscar eventos que sucedan en el propio componente web. Es parte de toda esta mentalidad de encapsular funciones y eventos dentro de un componente. Eso es todo lo que quería hablar sobre el tema de la especificación de elementos personalizados. En el siguiente video, vamos a hablar del DOM Sombra. 6. El DOM: Bienvenidos de vuelta, chicos. En este video, vamos a recoger donde lo dejamos con el último video en cuanto a nuestro pequeño proyecto aquí. Pero vamos a pasar a algo llamado la especificación Shadow DOM, que como aprendimos en la sección de teoría, es una forma en que podemos adjuntar un sub-árbol DOM a un Componente Web que es separado del DOM principal. Entonces tenemos nuestro DOM principal aquí como representado por nuestro HTML. Podemos crear lo que se llama un DOM Sombra en nuestro Componente Web o en cualquier elemento para ese asunto. Y ese DOM está separado a lo que a veces se conoce como el Dom de la Luz, que es sombra y luz son opuestos. Por lo que llamar al DOM Regular el Dom de la Luz es una manera diferenciarlo del Dom Sombra. Podrías oírme referirme al DOM Normal como el Light Dom en este video. Así que sólo una nota ahí. Entonces lo que voy a hacer es eliminar parte de este código para los eventos personalizados. Es un poco de código tonto de todos modos, eso fue sólo para demostrar un punto. Entonces voy a deshacerme de esa devolución de llamada conectada y ese evento especial. Realmente no necesitamos, dejaré ahí el Callback desconectado. Y voy a ir por aquí y simplemente eliminar todo este JavaScript adicional del documento HTML. Así que vamos a saltar directamente y adjuntar un Shadow Dom a nuestro Componente Web personalizado. Cómo hacemos esto es muy sencillo. Lo que hacemos es ejecutar el método, adjuntar sombra. Y lo hacemos en la palabra clave esta que se refiere al Componente Web, por supuesto. Y todo lo que tenemos que hacer es pasar en un objeto JavaScript. Y vamos a pasar en la modalidad de “abierto”. También podemos pasar en la modalidad de “cerrado”, pero es bastante irrelevante. Se puede mirar hacia arriba por qué pasaríamos en abierto o cerrado haciendo alguna investigación, pero no es particularmente importante en este momento. Entonces lo que voy a hacer es en lugar de tener nuestro HTML insertado directamente en el elemento, lo que voy a hacer es poner aquí sombra Root. Ahora, esta es una palabra clave especial que nos permite adjuntar este HTML interno a la raíz de la sombra, que es el inicio del sub-árbol DOM dentro de nuestro básicamente Shadow DOM. Permítanme guardar lo que ya es. Cambia a nuestro HTML. Tengo un diagrama aquí también. Por cierto, se abrieron entre clases. Te lo mostraré en tan solo un segundo. Y luego vamos a refrescarnos por aquí. Entonces vamos a entrar en elementos, y vamos a hacer clic en ese elemento. Ahora puedes ver que tenemos lo mismo que teníamos antes, pero también tenemos una raíz de sombra. Entonces entonces podemos hacer click aquí y echar un vistazo, y se puede ver que tenemos este HTML interno. Ahora la razón por la que tenemos este otro div ahí también, creo es porque no hemos cambiado esto a la raíz de la sombra. Por lo que voy a cambiar eso, refrescar por aquí. Y ahora se puede ver si entramos en nuestro Componente Web, no tenemos ese div y span adentro, pero lo que sí tenemos es un Shadow Dom. Y dentro de ese Shadow Dom, tenemos un div y el lapso, y por supuesto el botón que ya no hace nada dentro de ese Shadow Dom. Podrías estar pensando cuál es la diferencia entre adjuntarlo al Shadow Dom versus adjuntar este HTML directamente al Componente Web. Y me alegra que te estés preguntando eso porque de eso es exactamente de lo voy a hablar ahora en esta siguiente tabla. Entonces básicamente, lo principal con Shadow Dom es CSS. Dado que el Shadow Dom está separado al DOM principal, no hereda el CSS del Light Dom, como podemos ver aquí en esta tabla. Si voy al contenido Shadow Dom, el CSS Light Dom no aplica. En el otro lado, cualquier CSS dentro del Shadow Dom no se aplica al propio Componente Web ni a ningún contenido externo. Sin embargo, podemos pasar esto usando el pseudo-selector host de colon, del que hablaremos en tan solo un segundo. Entonces, básicamente, esta tabla resume la relación entre Light DOM CSS y Shadow DOM CSS en lo que respecta al propio Componente Web, contenido ranurado dentro de ese Componente Web, y el Sombra contenido DOM. Voy a pasar por cada uno de estos ejemplos muy pronto, pero empecemos con un ejemplo básico para empezar aquí. Esto es una especie de saltar adelante en el siguiente video, pero voy a crear una ranura. Así que déjame entrar en componente aquí. Y en lugar de botón, lo que voy a hacer es crear una ranura. Sólo voy a copiarlo aquí abajo también. Por supuesto, cualquier contenido que me mueva aquí, iremos a donde se ha establecido nuestra etiqueta de ranura. Entonces lo que voy a hacer es crear un lapso y decir que esto es un elemento ranurado. Y entonces lo que voy a hacer es empezar a escribir algún CSS en nuestro Light Dom. Entonces voy a apuntar el lapso y le voy a dar un color de rojo. Golpea “Guardar” en esa actualización de aquí. Y se puede ver que esto es un elemento ranurado y el color es de hecho rojo. Pero lo que puede haber notado también es que dentro de este div hay otro lapso. Y ese lapso no asumió el CSS en nuestro Light Dom y eso es porque es parte de la raíz de la sombra. Entonces si quisiéramos dar estilo a esta etiqueta en particular, lo que haríamos es entrar en el componente aquí, y en cualquier lugar donde creamos nuestro HTML, creamos una etiqueta de estilo separada. Y luego podemos colorear nuestro lapso como tal. Hagámoslo verde. Y de nuevo, no el código más limpio, pero tenemos que copiar esto aquí también. Le pegaré a “Guardar” en eso y luego refrescaré por aquí. Se puede ver que el palmo Shadow Dom es verde y el palmo ranurado es rojo. Entonces esto es lo básico del estilo del Shadow Dom. Si tienes un elemento dentro del Shadow Dom, el estilo normalmente tiene que suceder dentro del Shadow Dom también. Y eso no afectará ningún lapso que esté ranurado. Por el contrario, cualquier elemento dentro del Dom Sombra no heredan los estilos del Dom de la Luz. Entonces como viste aquí, cuando puse una regla de estilo para el color rojo en tramos dentro del Light Dom, eso no se aplicaba al lapso dentro del Dom Sombra. Entonces ese es el ejemplo básico de estilizar al Shadow Dom. Pero en realidad volvamos a nuestro diagrama aquí y pasemos por todos los diferentes escenarios. Entonces el primer escenario usando el CSS Light Dom para dar estilo al propio Componente Web. Lo que quiero decir con eso es igual que estamos usando el nombre del elemento para orientar este lapso. También podemos hacer eso con un Componente Web. Entonces funciona igual que cualquier otro elemento HTML. Podemos simplemente escribir Componente Web y digamos simplemente decoración de texto, subrayar, guardar y actualizar sobre eso y se puede ver que todo el Componente Web tiene un subrayado ahora. Volviendo aquí al CSS Shadow Dom, en realidad podemos estilizar el propio Componente Web desde dentro del Shadow Dom mediante el un host especial pseudo-selector de dos puntos. Así que volvamos y hagamos eso ahora. Entonces Si entro en nuestro componente aquí, y antes de que hagamos ese lapso de verde, hagamos hospedaje. Tal vez hagamos que el peso de la fuente sea negrita de todo lo que hay en el componente web. Le pegaré a “Guardar” en eso, refrescaré por aquí. Eso no funciona debido a este cambio de atributo callback. En realidad limpiemos esto ahora y hagamos este código limpio. En lugar de establecer exactamente el mismo código dos veces, lo que haré es dirigiré el span específico aquí y actualizaré ese valor al nuevo valor. En lugar de establecer el HTML interno explícitamente en la raíz de la sombra, volveré aquí, encontraré ese lapso particular en la raíz de la sombra, luego apuntaré al HTML interno de ese lapso, y luego estableceré eso en el nuevo valor. Eso es mucho más limpio. De esa manera mantenemos la estructura HTML interna de nuestra raíz de sombra sin tener que actualizar todo el asunto cada vez. Eso debería hacer que este trabajo ahora, lo que hace, ahora tenemos todo el componente web en negrita, y pudimos hacerlo dentro de la raíz de la sombra mediante el uso de este pseudo-selector de host. Volvamos a la mesa aquí. Veamos el contenido ranurado. El contenido ranurado en el contexto del DOM de Luz no se considera parte del DOM Sombra por lo tanto, los estilos Light DOM se aplican aquí. Ya vimos eso. Lo vimos en el caso de este lapso aquí que ha sido ranurado. El color de ese lapso es rojo. Nuevamente, como no se considera parte del DOM Sombra, aquí se aplican los estilos Light DOM. Pero como vimos antes con el selector de host, hay una manera de que podamos dar estilo este contenido ranurado dentro del Shadow DOM CSS también. Solo necesitamos usar la pseudo-clase ranurada de colon y tenemos que pasar en un parámetro. Vámonos y hagamos eso ahora mismo. Vamos a entrar en nuestro archivo component.js. Vamos a poner en esta pseudo-clase ranurada y el parámetro. Vamos a poner en el lapso para que estemos peinando el ranurado en lapso. Permítanme cambiar el color a, digamos, gris. Entonces si vamos por aquí y refrescamos, ¿qué crees que va a pasar? Vamos a averiguarlo. Como se puede ver, no hay cambio en estos colores. ¿ Por qué es eso? Si echamos un vistazo a este segundo elemento aquí, que es el elemento ranurado en, y miramos los estilos aplicados se puede ver que tenemos nuestro color rojo aquí, y luego tenemos nuestro color gris para el lapso pero el color rojo es sobrescribir. Esto es congruente con lo que he escrito en la tabla aquí que es, en el caso de los conflictos, los estilos del DOM Light tienen prioridad. Se podría pensar, he puesto esto último para que el gris se apoderara pero, en el caso de que haya un estilo para ese particular ranurado en contenido en el DOM Light, el estilo en el DOM Light llega a controlar el color. Si quisiéramos estilizar este ranurado en lapso dentro de nuestro DOM Sombra, tenemos que asegurarnos de que esto no esté ahí. Si comento eso fuera y luego refresco por aquí, se puede ver que podemos darle estilo a gris cuando no se sobrescribe por un estilo que se relaciona con el mismo elemento dentro de nuestro DOM de Luz. Refrescante por aquí, mantengámoslo en rojo, y volvamos a nuestra fila final aparte de la excepción aquí para contenido Shadow DOM en nuestra tabla. Cualquier Light DOM CSS no tendrá ningún efecto en nuestro DOM Sombra. Creo que ya podemos ver algunos ejemplos de esto. Podemos ver que hay una regla de color para el rojo en todos los elementos de span. Pero si entramos aquí, tenemos un lapso en nuestro DOM Sombra y, por supuesto, sigue siendo verde. Ya hemos visto eso y luego con el Shadow DOM CSS, obviamente, cualquier CSS que creamos en el DOM Sombra va a tener un efecto directo en el DOM Sombra. Nuevamente, vimos que con estilo de nuestro elemento span dentro del DOM Sombra, se puede ver que es verde. Eso es básicamente toda la mesa. La única excepción es Light DOM Las variables CSS son accesibles dentro del CSS Shadow DOM. Si has usado variables CSS antes, básicamente cómo funciona esto es, en nuestro Light DOM, podemos crear algunas variables CSS. Lo que voy a hacer es, en root, crear una variable CSS llamada color BG y lo estableceremos en negro. Entonces lo que voy a hacer es entrar a aquí y vamos a establecer el color de fondo a la variable de color BG, presionar “Guardar” en eso, refrescar por aquí. Se puede ver que a pesar la variable CSS fue definida en el DOM Light, todavía podemos traerla al DOM Sombra. Es solo que la regla CSS necesita estar en el Shadow DOM CSS. Esto nos da cierto control del contenido Shadow DOM en términos de usar variables dentro de nuestro DOM de Luz. Si tuviéramos un esquema de color, puedo cambiar esto a, hagamos esto amarillo y le pegamos a “Guardar” en esto. Ahora, se puede ver podemos actualizar valores dentro del DOM de Luz y eso afectará el DOM Sombra al usar variables. Pero aparte de eso, si fuéramos a entrar aquí y decir lapso, fondo, color de, ¿qué debemos hacer? Vámonos azules. esta regla de lapso dos veces así solo voy a comentar esa. Le pegaré a “Guardar”, refrescaré por aquí. Se puede ver el fondo azul solo se aplica al contenido ranurado. No se aplica al lapso dentro del DOM Sombra. En realidad no podemos cambiar este color a través del DOM de Luz a menos que, por supuesto, hagamos referencia a estas variables. Si alguna vez se pierden, los vincularé a esta mesa de aquí mismo. Pondré un enlace en tu pantalla ahora mismo para que puedas ir a comprobarlo cuando publique esta clase. Pero esencialmente el DOM Sombra se trata principalmente de CSS. Es una forma para nosotros arreglar el CSS de un elemento quizá si estuviéramos compartiendo elementos a través de diferentes proyectos y queríamos que el elemento luzca exactamente igual, sin importar en qué proyecto estuviera, el DOM Sombra sería útil. Pero dentro de tus propias aplicaciones privadas y páginas web, no estoy seguro de que el Shadow DOM sea demasiado requerido, por eso no lo vamos a utilizar en el ejemplo práctico al final de esta clase. Pero es popular dentro de los componentes web por lo que era importante aprender esta lección sobre el DOM Sombra. Como siempre, todo esto va a estar comprometido con GitHub, por lo que puedes esperar este código más adelante. Yo, por supuesto, compartiré esta mesa contigo pero eso resume más o menos el DOM Sombra. En el siguiente video, hablemos de slots y plantillas. 7. Ranuras y plantillas: Bienvenidos de vuelta chicos. En este video vamos a hablar slots y plantillas, que son bastante básicas. Ya usamos una ranura en el video anterior. Lo ranuramos en algún contenido aquí. Básicamente anidamos un lapso dentro de este componente web y luego pudimos elegir dónde queríamos que se deslizara hacia esta estructura HTML particular dentro de nuestro DOM sombra. Al echar un vistazo a eso en el navegador real, puedes ver que tenemos nuestra raíz de sombra aquí. Si entro al div y entro en este contenido ranurado aquí, se puede ver que hay un enlace a lo ranurado en contenido que está aquí mismo. Es una cosa rara donde técnicamente no es parte del DOM sombra, pero está ranurado en el DOM sombra aquí a través de esta etiqueta de ranura. Ahora ya hemos visto que en la práctica, lo siguiente a mirar es nombrar las ranuras, así que si queremos usar múltiples ranuras dentro de un componente web en particular. Para demostrar esto, voy a eliminar todo el código que realmente no necesitamos para esta demostración. De nuevo, podemos dejar en la devolución de llamada desconectada, pero voy a deshacerme de este atributo aquí. Deshazte de eso. Entonces voy a deshacerme del atributo tal como existe aquí en el HTML. Voy a crear otro lapso aquí. Entonces voy a escribir este lapso también ha sido ranurado. Si pego, “Ahorra” en eso, veamos qué pasa ahora. Si refresco la página se puede ver hay dos tramos dentro de esta ranura. Pero lo que podemos hacer a través de ranuras de nombre es encajar estos dos tramos en diferentes partes de la misma estructura HTML. ¿ A qué me refiero con eso? Bueno, pasemos a nuestro archivo component.js aquí y cambiemos esto. Digamos que tenemos dos divs. El primer div va a tener un **** para el primer lapso y vamos crear otro div que se separe a ese div y dentro va a ser el segundo lapso que muestro en mi componente web. Una vez que nombramos estas ranuras, lo que va a pasar es que este lapso va a entrar en la primera ranura y este lapso va a entrar en la segunda ranura. Podemos empezar ya sea en el documento HTML o en el documento JavaScript. Voy a empezar aquí en el JavaScript, todo lo que tengo que hacer es nombrar la ranura agregando aquí el parámetro name y luego aquí solo voy a llamarlo Ranura 1. Entonces voy a bajar al segundo slot y nombrarlo Ranura 2. Entonces más en nuestro index.html para enlazar estos hacia arriba es que voy a usar el parámetro slot, y voy a volver a usar ese nombre, así que la Ranura 1, y luego slot es igual a Ranura 2. Ahora si pego, “Guardar” y refrescar por aquí, ¿qué crees que va a pasar? Vamos a refrescarnos y echemos un vistazo por dentro. Como pueden ver, tenemos nuestros dos elementos ranurados por aquí, pero en cuanto a dónde encajan en nuestra estructura de raíz de sombra, abramos a este chico malo y podemos ver que tenemos dos divs. En el primer div, tenemos el primer contenido ranurado, y en el segundo div, tenemos el segundo contenido ranurado. Ahora están en divs separados y podríamos necesitar eso para todo lo que necesitemos hacer con nuestra estructura HTML, así que estilismo y todo eso. Así es como podemos ranurar en múltiples cosas en diferentes partes de nuestra estructura de sombra DOM. Siguiendo con esto, lo siguiente que quiero mostrarte son las plantillas. Voy a quitar este código justo aquí [RUIDO] entonces voy a poner en un HTML, las reglas de estilo y voy a volver a index.html aquí. Voy a dirigirme aquí y eliminar este contenido porque lo que vamos a hacer es poner contenido dentro de una plantilla y luego llevar ese contenido al componente web. Podemos hacer esto una de dos formas. Estoy seguro que podemos hacerlo de múltiples maneras, pero hay dos formas en que te voy a mostrar en este video. Podríamos poner la etiqueta de plantilla fuera del componente web. En este caso, vamos a darle una identificación. Sólo lo voy a llamar plantilla por el sake de simplicidad. Entonces aquí, vamos a crear nuestra plantilla. Simplemente haré un h1 y diré que este código de plantilla conforma el componente web. Entonces voy a crear una etiqueta de párrafo y usando Emmet dentro de Visual Studio Code, puedo escribir Lorem hit, “Tab” y generará Lorem Ipsum automáticamente. Sólo voy a arreglar el espaciado aquí para que ustedes puedan ver todo el párrafo. Golpe, “Guardar” en eso. Ahora, debido a que esta es una etiqueta de plantilla, no se renderizará en tiempo de ejecución. Si vuelvo aquí, ejecute el código, verá que tenemos nuestro código de plantilla aquí. Tenemos este fragmento de documento aquí, así que sí tenemos el código en nuestro HTML, pero nada es renderizado y eso es porque está dentro de una etiqueta de plantilla, lo que significa que no va a renderizar a menos que tomemos ese código de plantilla y renderizarlo usando JavaScript. Eso es exactamente lo que estoy a punto de hacer. Voy a volver a nuestro editor de código aquí y me dirijo a component.js. Lo que voy a hacer es después de establecer nuestro HTML interno aquí, que es sólo la etiqueta de estilo, lo que voy a hacer es encontrar ese código de plantilla. Cómo puedo hacer eso es mediante selector de consultas de documentos. Básicamente solo quiero encontrar ese elemento. Era una plantilla con el ID de plantilla. Por eso he puesto hachís delante de él. Entonces voy a encontrar el contenido de eso y luego voy a ejecutar clone Node con el parámetro de true. Con el parámetro de true que representa un clon profundo, por lo que cualquier subelemento dentro la plantilla se renderizará también. Realmente no puedo pensar en una situación en la que te gustaría correr falso aquí. Sólo mantengámoslo con verdad. Por supuesto que vamos a necesitar usar eso algo. Voy a guardarlo en una variable, una constante primero. Ahora, tenemos nuestra plantilla de const. Parece que accidentalmente he colocado esto fuera de la función constructor, así que voy a poner eso de nuevo ahí. Perdón por eso. Ahora, con esta plantilla, lo que puedo hacer es que puedo adjuntar ese nodo clonado a la raíz de sombra. Voy a agarrar la raíz de sombra aquí y ejecutar anexar a un niño, colocando ese código de plantilla ahí como argumento. Vamos a refrescar la página por aquí y ver qué pasa. Ya puedes ver que ahora tenemos el código de plantilla funcionando dentro de nuestro componente web. Si entro en el código del componente web aquí, puedes ver que tenemos nuestra raíz de sombra y dentro de la raíz de la sombra tenemos la etiqueta de estilo que configuramos configurando explícitamente el HTML interno. Entonces tenemos la etiqueta h1 y p que configuramos en la plantilla. Lo que también podemos hacer para hacer esto un poco más simple y encapsulado es poner la etiqueta de plantilla dentro del propio componente web. Sólo voy a copiar eso y luego comentarlo. Vayamos dentro del componente web. Ahora, porque estamos dentro del componente web, solo podemos hacer referencia al elemento template en lugar de tener un ID. Voy a golpear, “Guardar” en eso y luego ir aquí a nuestro código y lo que podemos hacer en su lugar es quitarle este hash. En lugar de documento, podemos decir esto. Esto buscará cualquier plantilla dentro de nuestro componente web. Voy a golpear, “Guardar” en eso, refrescar por aquí, y ya ves que obtenemos exactamente el mismo resultado. Se puede ver que la plantilla está en el componente web y luego el código que teníamos en esa plantilla ha sido clonado dentro del DOM sombra. Esto funciona igual que si no estuviéramos usando el DOM de sombra en absoluto. Simplemente quitemos la sombra DOM por completo. En realidad, sólo voy a comentar porque creo que podríamos usarlo en el siguiente video. Vamos a anexarlo al HTML interno real. Refresca aquí y verás que no se va añadiendo y eso es porque todavía tenemos raíz de sombra aquí. Esta actualización de hijo anexa por aquí. Nuevamente, no funciona. ¿ Qué hemos hecho? No se pueden leer propiedades de null. Creo que el tema aquí es que hemos establecido en nuestro HTML explícitamente, que está eliminando el contenido HTML dentro del componente web que hemos puesto aquí, que es solo esta etiqueta de plantilla. En este caso, lo que haría es que me dirigía por aquí y simplemente nos deshacemos de esto y su lugar pondría esto directamente en la plantilla, que es un poco más limpia de todos modos. Vamos a “Guardar” en eso y luego al lado de la plantilla, pondré la etiqueta de estilo directamente en nuestro HTML. Golpeé “Guardar” en esa actualización por aquí y el tema se ha ido ahora. Dependiendo de cómo quieras hacerlo, esto realmente se ve bastante limpio porque no estamos poniendo ningún HTML dentro del JavaScript en absoluto. Estamos poniendo todo el HTML y los estilos que entran dentro de nuestro componente web. Pero debido a que ya no estamos usando un DOM de sombra, estos estilos teóricamente se aplicarán a todo. Si entramos aquí y ponemos un lapso, digamos que esto es un lapso. Refresca por aquí. los estilos de nuestra luz DOM que tenemos aquí arriba y nuestros estilos aquí dentro del componente web ambos se aplicarán. Si le doy un vistazo a esto, echemos un vistazo a este lapso particular aquí. Se puede ver que el color de fondo azul y el color de fondo amarillo se están aplicando. Pero debido a que esto está sucediendo más adelante en el documento, está anulando a éste de aquí mismo. Esencialmente, no tiene sentido que tengamos aquí una etiqueta de estilo si pretendemos que esto solo se aplique al componente web, en ese caso, querríamos pegarnos con el DOM sombra. Sólo voy a retroceso aquí y de vuelta por aquí. Vamos a mantener el DOM sombra, refrescar por aquí. Entonces si iba a agregar un lapso a nuestra plantilla aquí, actualízate. Inspeccione ese elemento. Se puede ver que ninguno de los estilos de la luz DOM se están aplicando aquí porque este código de plantilla se está poniendo en una sombra DOM y luego, solo los estilos que tenemos en nuestra raíz de sombra se aplicará a ella. Cosas bastante simples de plantillas aquí, mucha flexibilidad dentro de esto, pero esencialmente, todo lo que se necesita es crear una etiqueta de plantilla y entonces lo vamos a hacer es básicamente encontrar esa plantilla, mira su contenido, y ejecuta clone Node para crear un nodo DOM o un sub árbol DOM basado en esa plantilla y luego podemos anexarlo donde queramos en nuestro componente web, ya sea a la raíz de sombra o a el HTML interno directamente. Eso cubre ranuras y plantillas. En el siguiente video, vamos a cubrir elementos incorporados personalizados. 8. Elementos de Built-in personalizados: Muy bien chicos. En este video vamos a cubrir elementos incorporados personalizados. Entonces hasta este punto, hemos estado extendiendo la raíz HTMLElement. Pero ahora vamos a extender un HTMLElement específico, y esto es lo que se conoce como construir un elemento incorporado personalizado. Entonces lo que voy a hacer es eliminar todo este código porque estamos creando un elemento completamente nuevo y porque estoy haciendo eso, voy a entrar en mi índice por aquí y eliminar todo este código también. También podríamos eliminar cualquier cosa dentro de nuestra etiqueta de estilo. Aquí tenemos una pizarra bastante limpia. Entonces para demostrar un elemento incorporado personalizado, voy a extender el elemento de botón HTML. Entonces lo que vamos a hacer es crear nuestro propio botón personalizado. Así que a partir de la misma manera que normalmente lo haríamos escribiendo clase y luego voy a llamar a mi elemento de botón personalizado, literalmente solo CustomButton. Entonces voy a escribir extiende y en lugar de escribir HTMLElement, lo que voy a hacer es HTMLButtonElement. Ahora si estás usando un editor de código o IDE, como Visual Studio Code, puedes ver después de escribir HTML, puedes ver una lista completa de todos estos diferentes elementos que puedo usar. El formato es básicamente HTML, el nombre del elemento y luego elemento. Para que pueda extender un elemento de encabezado. Puedo extender un elemento de imagen, un elemento de entrada, una etiqueta, un enlace, tantas opciones diferentes aquí. Entonces, si necesitas navegar por las diferentes opciones, no estás seguro de cuál es el nombre de la clase, entonces esto realmente ayuda. Pero lo que estoy buscando es un HTMLButtonElement, así que voy a golpear eso. Entonces vamos a abrirla como lo hicimos la última vez. Voy a escribir nuestro método de definición CustomElements como lo hemos hecho anteriormente para los componentes web estándar, y voy a hacer que la etiqueta custom-button. Entonces como segundo argumento, como de costumbre, vamos a poner esa clase en pero aquí es donde vuelve a ser diferente. Tenemos que poner en un tercer argumento. Tenemos que poner en un objeto JavaScript con un par de valores clave. La clave va a ser extiende y el valor es la etiqueta del elemento que estamos extendiendo así que para un botón HTML, la etiqueta es por supuesto botón. Si tuviera que escribir esto en el HTML, será así que básicamente estás tomando la palabra que está en medio del menos que y mayor que firmar y poniéndola aquí después de extiende. Si este fue un enlace personalizado por ejemplo, permítanme engañar usando auto-completar allí. Si estuviéramos extendiendo tu elemento de enlace HTML, esto cambiaría a 'a', porque eso es lo que se representa la etiqueta de anclaje como en el HTML. Pero estamos haciendo botón así que voy a Control Z hasta que volvamos al botón. Entonces como lo hemos hecho anteriormente con componentes web estándar, voy a crear aquí un constructor y luego por supuesto voy a ejecutar super para que podamos heredar la función constructor de la clase que estamos extendiendo, que era HTMLButtonElement. Entonces lo que voy a hacer es dirigirme a nuestro index.html aquí y escribir algo de HTML. En realidad vamos a crear ese elemento incorporado personalizado. La forma en que hacemos eso es diferente a los componentes web estándar. En realidad vamos a utilizar el nombre original del elemento que estamos personalizando. Va a ser botón. Dentro de este botón, sólo voy a escribir presionarme y luego aquí para convertirlo en nuestro elemento incorporado personalizado y no sólo un botón estándar, vamos a usar el atributo de is. Entonces dentro de aquí, botón personalizado, que coincide con lo que hemos escrito en el primer argumento de nuestro método definido aquí. Volviendo aquí, lo que podría hacer por este ejemplo es que voy a poner en un enlace. Voy a poner en un atributo personalizado de link y sólo vamos a conseguirlo para ir a google.com. Entonces esto sería como el comportamiento estándar de una etiqueta de enlace quizás. Por lo que escribiríamos href, y luego si hacemos clic en el enlace, iría a esa URL específica. En este caso, si acabo de hacer esto en este momento y vuelvo a nuestro código por aquí y hago clic en “ Presionarme” nada va a pasar porque este es un atributo personalizado. No va a hacer nada a menos que escribimos algún código en nuestro componente aquí para manejar eso. Entonces eso es exactamente lo que voy a hacer a continuación. Voy a agarrar ese valor para que esto.getAttribute. Entonces voy a poner el nombre del atributo en su link y luego por supuesto voy a guardar eso en alguna parte. Voy a almacenarlo en el propio componente web, así que voy a decir que esto.link es igual al valor de this.getAttribute link. Si quisiera, también podría hacer si esto tiene atributo como lo hicimos antes, pero solo voy a asumir que sí tiene eso porque tengo el control de escribir este código y voy a asegúrate de que tenga ese atributo. Entonces lo que voy a hacer es que voy a configurar un oyente de eventos. Si se hace clic en este elemento, así que haga clic en “Evento” entonces voy a ejecutar este código. Lo que voy a hacer es cambiar la ubicación de la ventana href al valor de this.link. Lo que hemos hecho aquí es que hemos tomado el valor dentro del atributo link, lo almacenamos en esta variable y luego hemos hecho un oyente de eventos para el evento click en este botón personalizado. Cuando se haga clic, va a redirigir al usuario a lo que almacenamos en ese atributo link. Entonces probemos si esto funciona. Ahora, voy a refrescar por aquí y voy a hacer clic en “Presionarme”, y como pueden ver, vamos a google.com. Ahora de nuevo, no es el ejemplo más práctico porque podríamos haber utilizado simplemente una etiqueta de enlace para esto. Pero permítanme simplemente extender este ejemplo un poco más allá. Porque tenemos aquí un elemento que está heredando todo el comportamiento original de un elemento de botón, tal vez tengamos que evitar que se comporte como un botón. Un ejemplo de esto sería si estuviera dentro de un formulario. Voy a tener un formulario aquí y voy a poner la acción a punto final como ejemplo. Esto obviamente va a enviar el formulario a ninguna parte porque en realidad no tengo un punto final. Eso se llama punto final. Entonces si presiono “Guardar” en eso y refresco por aquí y hago clic en “Presionarme”, verás que hereda el comportamiento de un botón dentro de un formulario, que es enviar el formulario. Entonces aquí se puede ver que vamos a este punto final aquí que no existe. Entonces esto es por supuesto diferente a si tuviera una etiqueta de enlace porque tenemos una etiqueta de enlace, Número 1 no aparecería luciendo así porque no es un botón. Número 2, una etiqueta de enlace no activa una cumbre de una forma si está dentro de uno. Entonces lo que podemos hacer es que pueda pasar a component.js aquí y puedo ir event.preventDefault. Se guarda en esa actualización de aquí. Si hago clic en esto, aunque esté dentro de un formulario, va a evitar ese comportamiento predeterminado y luego va a hacer lo que le hemos dicho que haga, que es redirigir al usuario a cualquiera que sea la dirección en el atributo link. Volviendo aquí, sólo para perforar esta casa, si tuviera que poner en un botón estándar que no fuera uno de nuestros elementos incorporados personalizados y decir que me puedes presionar también y luego me refresco por aquí. Si hago clic en el me puedes presionar también, va a actuar como un botón estándar y enviar el formulario. Pero debido a que hemos personalizado este otro botón para evitar defecto y en su lugar redirigir al usuario a google.com, se va a comportar de manera diferente. Por lo que ojalá de nuevo, no el ejemplo más práctico, pero ojalá esto comunique lo que podemos hacer con los elementos. Podemos tomar parte del comportamiento y atributos de un elemento que nos guste, y podemos modificarlos a nuestros fines. Obviamente, aquí hay montos locos de flexibilidad. Puedes tomar esto en la dirección que quieras, pero esto no es algo que utilicemos particularmente en la sección práctica de esta clase, solo algo que tener en cuenta porque sí cae bajo la especificación del componente web. Podemos extender elementos específicos aquí, y esto es lo que se conoce como elementos incorporados personalizados. Chicos, así que en el siguiente video, lo que vamos a hacer es cubrir la especificación final de la que aún no hemos hablado, que es la especificación de módulos ES. Te veré en el siguiente video. 9. ES Modules: Chicos, así que en este video final antes entrar en nuestro proyecto de clase práctica, hablemos de los módulos ES, que es la cuarta especificación dentro la meta-especificación de componentes web. Los módulos ES es esencialmente una forma para nosotros estructurar nuestro proyecto de manera diferente. Podemos poner cada uno de nuestros componentes en su propio archivo JavaScript modular y luego llevarlo a otro archivo JavaScript y luego traer ese archivo JavaScript a nuestro documento HTML. O alternativamente, podemos simplemente traer cada componente a nuestro documento HTML sin ese archivo. Pero en los ejemplos que te voy a mostrar, voy a importar todos los componentes en un solo archivo JavaScript, y luego vamos a colocarlo en nuestro documento HTML. Algunos proyectos, esto va a ser muy útil, algunos proyectos no va a tener sentido en absoluto. Vamos a utilizar módulos ES en la práctica que viene después de esta lección. Esto será algo que veremos en acción muy pronto pero para esta lección, realidad demostremos módulos ES. Como dije, lo que voy a hacer es que voy a importar todos nuestros componentes, ahora mismo hay sólo uno pero voy a hacer un segundo en un archivo JavaScript central, y voy a llame a ese index.js. Ahora lo que voy a hacer para ponernos en marcha, vamos a cerrar esto abajo para que podamos ver todo el asunto, es que voy a mover este elemento personalizado define método aquí y pasar eso a nuestro index.js. Para que tengamos acceso a esta clase justo aquí, lo que voy a tener que hacer es exportarla desde aquí y luego importarla a aquí. En primer lugar, porque sólo tenemos la clase única aquí, no voy a hacer una exportación con nombre, voy a hacer una exportación sin nombre. Acabo de exportar por defecto y luego el nombre de clase que quiero exportar. Lo que esto hace es exportar solo esta clase, así que una vez que la importe aquí, puedo referirla directamente en nuestro código aquí. Voy a ejecutar la declaración de importación aquí, estamos buscando botón personalizado y luego, después de la palabra clave from aquí, puse la ruta al archivo. Ahora, que he hecho eso, lo que necesito hacer es actualizar el código aquí así que en lugar de component.js, puse index.js. Como vimos en la lección de teoría, necesito cambiar o agregar el atributo aquí del módulo de tipo. Le pegaré, “Ahorra” en eso. Vamos a refrescarnos por aquí. Deberíamos ver que todavía tenemos estos botones pero si hago clic en el primero, que es nuestro elemento incorporado personalizado, se puede ver que tenemos la misma funcionalidad que un botón estándar. Ambos son exactamente iguales. El motivo está justo aquí en nuestra Consola JavaScript. Tenemos un error de política CORS aquí y la razón por la que es porque realmente no podemos hacer esto ejecutando el HTML desde el sistema de archivos. Lo que tenemos que hacer es ejecutar un servidor. Eso es muy fácil dentro del código de Visual Studio. Ojalá también sea fácil y sencillo en tu IDE. Si no, siempre puedes usar Visual Studio Code y solo voy a bajar aquí y hacer click en Go Live. Ahora puedes ver que estamos ejecutando un servidor. La forma en que puedo ver eso es porque tenemos aquí una dirección IP en lugar de una ruta desde el sistema de archivos. Ahora, si presiono Command Option I para sacar la consola, no se ven errores y si hago clic, “Presioname”, me llevará a Google en lugar de ese punto final que está buscando aquí. Voy a cerrar éste en el sistema de archivos y solo usaremos éste. Aquí, se puede ver todo esto ya funcionando. Hemos importado código de component.js a index.js, y luego lo hemos importado a index.html. Pero esto realmente no tendrá sentido, y por eso hemos creado otro componente. Voy a crear un segundo componente aquí. Esto es terrible nomenclatura pero sólo voy a llamarlo component-2. ¿ Sabes qué? Solo por diversión, vamos a crear otro elemento incorporado personalizado. Voy a escribir clase y vamos a extender el elemento link para crear un enlace personalizado. Voy a escribir enlace personalizado extiende HTML, elemento de anclaje. Abre eso aquí, obviamente voy a poner el constructor. Entonces voy a llamar super como siempre lo hemos hecho. Para esto, lo que podría hacer es agregar event-oyente para click, [RUIDO] esto es similar a lo que hicimos antes pero ahora tenemos el comportamiento predeterminado de una etiqueta de anclaje. Lo que voy a hacer es básicamente hacer de esto un enlace de confirmación. Voy a ejecutar Confirmar y pedirle al usuario que confirme que quiere usar Google. Quieres usar Google y luego si eso vuelve tan falso como puedes ver a partir de este signo de exclamación aquí, entonces voy a evitar el default. Voy a evitar que el usuario use ese enlace. Bastante ejemplo básico ahí. Entonces por supuesto, voy a exportar eso, y como solo estamos exportando una clase, puedo usar por defecto aquí. Vamos a exportar enlace personalizado, y luego vamos a entrar en index.js y usar el mismo formato. Voy a importar botón personalizado desde component2.js y luego escribiremos nuestro método definido aquí abajo, así que elementos personalizados, definirlo, llámalo enlace de guión personalizado. Entonces ponemos el nombre de la clase, es el segundo argumento. Entonces en nuestros extiende aquí, vamos a estar extendiendo el elemento de anclaje estándar, que se acaba de representar como un en el HTML. Si entonces me dirijo a mi index.html, ya estamos importando todo este código. Todo lo que necesito hacer es simplemente escribir una etiqueta aquí. Hagámoslo para ir a Google de nuevo. Entonces por supuesto, para asumir la funcionalidad de este elemento incorporado personalizado, voy a tener que escribir es y luego dentro del atributo is, poner en el nombre que especifiquemos cuál es enlace personalizado y luego solo voy a hacer clic derecho en mí para ir a Google. Golpe, “Guardar” en eso. Vamos a refrescarnos por aquí. Se puede ver el enlace ahí. Ni siquiera tuvimos que actualizar porque estamos usando Live Server, que es solo una característica dentro de Visual Studio Code. Esto se llama recarga en caliente. Entonces si hago click en esto me va a preguntar si definitivamente querría ir a Google. Si hago clic, “Cancelar”, va a evitar el comportamiento predeterminado, que me está dirigiendo a esa dirección. Pero si hago clic en él y hago clic, “Está bien”, me va a dirigir ahí. la funcionalidad dentro del componente real Sin embargo, la funcionalidad dentro del componente real en sí no es el punto aquí. El punto es nuestra capacidad para exportar clases de documentos JavaScript a otros documentos JavaScript y a documentos HTML mediante el uso de módulos ES. Ojalá, ese es un concepto genial para ustedes chicos que acaban de aprender. En el siguiente video, vamos a empezar a construir esto como una aplicación práctica. En ese video, tal vez múltiples videos dependiendo del tiempo que vayamos, nos verás usando módulos ES en acción y así lo verás en la práctica un poco más en los próximos videos. Eso es básicamente las cuatro especificaciones para la meta-especificación del componente web. En realidad pongamos esto en práctica en el siguiente video y creamos nuestro propio proyecto personalizado. 10. Componentes web en la práctica, parte 1: Muy bien, todos. Bienvenido a la parte práctica basada en proyectos de la clase. Recibo la retroalimentación con bastante regularidad de ustedes chicos que quieren ver ejemplos más prácticos. En este curso hasta ahora, no hemos visto demasiados de ellos si estoy siendo honesto. Sin tener unos pocos componentes web trabajando juntos y sin un caso de uso, es difícil demostrar casos prácticos reales de uso componentes web y muchas de estas especificaciones que no necesitas usar en la única vez. Por ejemplo, en este proyecto que estamos a punto de crear, no estoy usando el Shadow DOM en absoluto porque no siento la necesidad de usarlo a menos que esté tratando de mantener mi DOM Sombra separada y lo que quiero decir con separado como en el estilo CSS separado sabio al resto de mi proyecto. Si estoy en control de mi propio proyecto, entonces realmente no siento la necesidad de tener que crear un DOM Sombra porque sí, tal vez sí quiero que los estilos del DOM de Luz afecten al DOM Sombra. Mezcle y combine cualquiera de las características de cualquier especificación que tenga sentido para usted. Espero que hayan aprendido algunos buenos fundamentos en esta clase, pero quería incluir una lección más práctica basada en proyectos para ustedes chicos. Esto probablemente tendrá que dividirse en múltiples lecciones, por lo que esto podría aparecer como múltiples videos dentro de esta clase de Skillshare. Pero lo que quiero hacer es crear un ejemplo práctico, el ejemplo más práctico que puedo pensar y usar ese ejemplo práctico que vimos anteriormente en la clase con el ejemplo de e-commerce vía Shopify para crear nuestro propio proyecto inspirado en el comercio electrónico, y si quieres llevar este proyecto más allá, úsalo como inspiración para algo que quieras usar en el mundo real. Siéntase libre de hacerlo. Pero en lugar de, yap más sobre ello, quiero simplemente saltar directamente en él y dejar que ustedes sigan junto con lo que estoy creando aquí. Para este proyecto, voy a comprometer todo en Git para que puedas mirar este código más tarde y comparar tu código con él. Eso ha sido una crítica de algunas de mis clases en el pasado también, es que ustedes no han podido realmente mirar el código en sí aparte de en los videos. Yo los he escuchado chicos en eso también, y así que voy a estar comprometiendo como voy y ustedes pueden mirar este código en GitHub después se publique esta clase y comparar su código con el mío. Sin más preámbulos, vamos a meternos en ello. Voy a crear una carpeta de proyecto aquí dentro de la carpeta de código donde creamos la otra carpeta. Voy a llamar a este carro de compras. Después trae Visual Studio Code, luego toma esta carpeta, arrástrela a Visual Studio Code, y por lo tanto, sé que estoy abriendo esa carpeta en particular. Obviamente, extenderé esto hasta el ancho completo de su visualización. Ahí vamos, y empecemos con nuestro contenido de calderas. Entonces voy a crear un nuevo archivo con index.html. Lo mismo que he hecho en el pasado, usa el signo de exclamación para generar un documento HTML de calderas. Llamemos a este carrito de compras. Entonces lo que voy a hacer es copiar en algunos activos, CSS y activos de imagen porque esta clase no está realmente en CSS, y por supuesto no voy a ir a conseguir que consigas tus propias imágenes, así que voy traen esos ahora mismo. Solo echemos un vistazo rápido que sepas lo que está pasando. Acabo de tener un archivo styles.css aquí y solo tiene un montón de código diferente. Este es redundante. Pero tenemos un montón de código diferente aquí solo para dar estilo a nuestro proyecto muy bien. Nuevamente, realmente no estamos enfocados en los estilos de esta clase, pero es mucho mejor tener un proyecto que tenga un estilo agradable que uno feo. Así que tengo eso ahí dentro y luego tengo imágenes aquí, productos aleatorios. Estas son imágenes aleatorias de productos como se puede ver. Todos se ven visualmente similares, pero no hay relación entre Coca-Cola Cero, y Aceite de Semilla de Cáñamo, y Pasta de Curry Rojo. Un poco aleatorio, pero solo necesitábamos algunas imágenes de marcador de posición para este proyecto. También voy a crear una carpeta JavaScript. Comienza haciendo clic en “Nueva carpeta”, “js”. Dentro de esta carpeta js, voy a crear un index.js. Lo que voy a hacer aquí es porque vamos a estar construyendo un carrito de compras, voy a crear un objeto en el objeto ventana. Será un objeto global llamado cart, y luego voy a abrir un objeto vacío, y sé que en este objeto quiero tener una matriz de elementos, así que solo estoy inicializando eso aquí mismo. Voy a golpear “Guardar” en eso, y este probablemente será mi primer compromiso. Voy a traer aquí una terminal, ejecutar git init, git add. y luego git commit inicial. Claro eso, y entonces lo que voy a hacer es que trataré de comprometerme cada tanto para que ustedes puedan ver el progreso sucediendo y puedan referirse al código si lo desean. Tenemos esta **** DS Store aquí. Sólo voy a descartar eso, en realidad no necesito eso. De vuelta a nuestro código aquí, demos nuestro primer paso para crear este proyecto. En realidad, antes de que hagamos eso, hagamos clic en “Go Live”. Ahora verás que estamos ejecutando nuestro archivo index.html. También necesitamos cargar en esos estilos, por lo que probablemente debió haber hecho eso antes de mi compromiso inicial. Pero aquí vamos, enlazamos rel="stylesheet” y luego el camino a esa hoja de estilo es css/styles.css. Ahora antes de construir cualquier funcionalidad, solo voy a crear algo de HTML aquí, así que vamos a crear un div con la clase de contenedor, cosas bastante estándar, y luego h1 carrito de compras. Entonces lo que voy a hacer es un div con la clase de productos a la venta, y luego dentro de aquí, lo que voy a hacer es crear cuatro divs, así div veces 4. Vamos a dar “Guardar” en eso. Vamos a mirar por aquí, entonces se puede ver si hago clic en el click “Inspeccionar en él” y ver productos a la venta. Tenemos todo el CSS listo para ir para cuando insertamos estos elementos de producto en este div aquí mismo. Antes de hacer nada, déjame darte una visión general de lo que estamos tratando de crear aquí. Este será nuestro proyecto terminado. Como puedes ver aquí, tenemos cuatro productos que podemos añadir a nuestro carrito, y si hago click en el botón Agregar al carrito debajo de cualquiera de estos productos, agregará ese artículo a nuestro pequeño carrito aquí. Si vuelvo a hacer clic en ese botón, aumentará la cantidad, si voy a hacer clic en el botón Agregar al carrito de otro producto, agregará esa línea a la tabla aquí, que es auto actualizando el total. Piensa que todos estos son alrededor de 10 dólares, por lo que es matemática bastante fácil, y también puedo actualizar la cantidad a través de estos selectores de cantidades, y eso actualizará los totales según corresponda. También puedo entrar aquí y poner esto a 10 si quiero. Entonces puedo establecer mi propia cantidad específica. La teoría detrás de esto es si fuera un verdadero carrito de compras, podría hacer clic en un botón y se dirigiría a comprobar hacia fuera con esa selección. Para nuestros fines, si refrescamos la página, perderemos nuestro carrito. Podríamos escribir algún código para persistir eso en almacenamiento local o almacenamiento de sesión. Pero para los efectos de este video, no creo que realmente necesitemos hacer eso, eso podría ser una mejora que usted haga en el futuro. Lo final que hace es, si está en uno y tratas de reducir la cantidad, solo quitará ese artículo del carrito. Si no hay artículos en el carrito, toda la mesa desaparecerá. Entonces eso es lo que estamos construyendo. Podría dejar esa pestaña abierta a un costado ahí, volver aquí, y vamos a trabajar. En realidad una cosa más antes de que empecemos en esto, quiero realmente dar un vistazo cómo vamos a romper esto en componentes web. Aquí puedes ver que tenemos cada uno de estos productos aquí y existe la misma funcionalidad en todos ellos. Si hago clic en el botón Agregar al carrito, agregará ese producto en particular al carrito, por lo que cada uno de estos productos va a ser su propio componente web. Entonces como pueden ver, si refresco aquí, haga clic en “Agregar al carrito” obtenemos esta otra sección agregada aquí, que es nuestra lista de artículos del carrito, la tabla de artículos del carrito. Eso va a ser un componente también. Entonces finalmente, dentro de ese componente de tabla de artículos de carrito, tenemos otro componente que es nuestro selector de entrada de cantidad aquí. Así que cada vez que haga clic más o menos, vamos a establecer una cantidad específica aquí, vamos a configurarla a cero. ver qué pasa, desaparece. Eso también va a ser un componente. Empecemos con el componente del producto. Vayamos aquí, y luego diríjase a nuestro editor de código. En nuestra carpeta js, vamos a crear el archivo para ese componente. Voy a llamarlo product.js. Empecemos con la calderilla. Voy a llamar a este elemento producto clase. Por supuesto, vamos a extender elemento HTML como hemos visto a lo largo de esta clase. Entonces antes de escribir cualquier código dentro, solo voy a exportarlo de inmediato. Debido a que estamos usando módulos ES con cada componente contenido en su propio archivo JavaScript, voy a usar export default y luego simplemente escribir el nombre de clase después de eso. Pulsa “Enter” en eso, luego cambiando a mi archivo index.js, voy a poner mi importación al inicio del elemento file products, y luego derecho desde la ruta a ese archivo, que ya estaban en la carpeta JavaScript, por lo que va a ser.product.js. Entonces tenemos que poner aquí un método definido, obviamente, los elementos personalizados definen. Solo voy a llamar a ese producto-elementos como el primer argumento, y luego traer esa clase de elemento de producto. También tengo que importar ese archivo index.js a HTML. No olvidemos eso. Script src=” js/index.js " y luego sin olvidar ese tipo atributo de módulo. Presione “Guardar” en eso, actualice por aquí, y vea si hay algún error de JavaScript que no haya. Perfecto. Regresemos la cabeza. En lugar de estos cuatro divs lo que quiero hacer es hacer cuatro elementos de producto. Vamos a dar “Save” en eso y nos dirigimos a aquí. Como de costumbre, voy a agregar el método constructor y luego ejecutar super. Ahora tenemos que hacer algo pensando en cómo queremos construir nuestro componente web personalizado aquí. Si miro el código aquí vamos a traer en este componente web cuatro veces diferentes. No sé si quiero escribir mi HTML interno dentro de cada uno de estos porque va a ser bastante repetitivo. Lo que podría hacer es que podría poner la estructura HTML dentro de la definición de clase de componente web justo aquí. De esa manera es lo mismo para cada componente web que es lo que queremos y eso mantendrá limpio nuestro código. Lo que voy a hacer es que voy a escribir este HTML interno. Esta estructura se basa en el CSS que ya he configurado. Se está aprovechando las clases ya en el CSS. Voy a crear un div con la clase de contenedor de imagen. Cierra eso y luego por dentro voy a tomar la imagen con una imagen de clase de producto. Entonces voy a poner en el SRC que en cuanto lleguemos aquí deberíamos empezar a pensar a nosotros mismos, este tiene que ser un valor dinámico. Si es un valor dinámico entonces realmente no podemos establecer algo explícitamente aquí porque entonces la imagen del producto va a ser la misma para cada producto. Obviamente, la estructura de cada elemento de producto va a ser la misma pero el producto va a cambiar, y por lo tanto la imagen del producto. Por lo tanto el título y el ID del producto todos van a cambiar. Ahora llegaremos a cada uno de esos a medida que venga. Pero para arrancarnos lo que quiero hacer es crear un atributo personalizado al menos para la imagen. De esa manera podemos pasar en la imagen en cada uno de estos componentes web. Vimos esto antes en la clase cuando miramos atributos personalizados ahora llegamos a usarlo en la práctica. Lo que voy a hacer es poner en un atributo de imagen y echemos un vistazo dentro de nuestra carpeta aquí. Hacemos que el camino hacia la imagen, image/coke-zero.jpg. Vamos a copiar eso a aquí y aquí y luego actualizaremos eso. El segundo será el aceite de semillas de cúñame. El siguiente será mágico-toque-cuerpo-crema y luego la final será pasta de grosella roja. Golpea “Guardar” en eso. Entonces lo que podemos hacer es dirigirnos a nuestro componente web aquí. Podemos configurar la imagen en los componentes web. Estamos configurando una variable adjunta a este componente web como lo hicimos antes, obtener atributo y vamos a obtener el valor de ese atributo de imagen. Entonces dado que tenemos ese valor podemos entonces entrar aquí e insertarlo aquí mismo en este SRC. Voy a golpear “Guardar” en eso, refrescar por aquí y vamos a ver qué tenemos. Van a consolarse, sin errores. Pero se puede ver que tampoco se está encontrando. Sospecho que esto es por algún error tonto. Sí, es un error tipográfico tonto. Debe ser elemento del producto no elementos del producto. Simplemente pasa y deshazte de esos S. Pulsa “Guardar” en eso y luego si nos refrescamos por aquí, en realidad ni siquiera tenemos que refrescarnos porque puedes verlo funcionando para nosotros. Veamos si todavía podemos ver las cosas. Sí. Vamos a poner esto por el fondo y luego se puede ver que tenemos nuestra alineación de las cuatro imágenes de productos. Tenemos la misma estructura para cada elemento de producto que almacenamos aquí pero estamos pasando por el valor dinámico de donde está la URL de la imagen y luego la estamos poniendo en nuestra estructura de plantilla aquí. Pero por supuesto, como mencioné antes la URL de la imagen no es el único contenido dinámico que necesitamos pasar a este elemento de producto. Necesitamos el título slash el nombre del producto. Necesitamos su precio y necesitamos su DNI. Vamos a crear algunos atributos para eso también. Continuemos con el siguiente en la jerarquía visual. Continuemos con el nombre. Voy a hacer exactamente el mismo formato que he hecho aquí. Cree una variable llamada this.name y luego obtenga el valor del nombre del atributo. Obviamente, esto no ha sido creado todavía. Voy a entrar aquí, voy a cerrar esto para que podamos ver esto mejor, y luego voy a crear un atributo de nombre para todos estos elementos de productos. Entonces éste va a ser coca cero. Voy a poner entre paréntesis, lata. Entonces aquí aceite de semilla de cáñamo y luego aquí sólo voy a llamarlo crema corporal y luego aquí pasta de curry rojo. Golpea “Guardar” en eso. Vayamos por aquí y entonces realmente necesitamos usar ese nombre en algún lugar de nuestro código. Puedo bajar aquí y luego puedo ir igual que lo hemos hecho con la imagen, crear un h2 dentro de este h2. Puedo deslizarme en esto.name. Refrescante aquí ya puedes ver el nombre de cada producto debajo de la imagen del producto. hay un poco de problemas CSS Aquíhay un poco de problemas CSSy eso es porque no se supone que esté dentro del contenedor de imágenes. Déjame arreglar eso. Se supone que está fuera de este div. Golpeé “Guardar” en esa actualización de aquí entonces ya puedes ver que ya no tenemos ese tema. Dulce. Eso conforma nuestra jerarquía visual. Pero lo otro que tenemos que hacer es realmente almacenar algunos datos en este elemento producto para cuando hacemos clic en “Agregar al carrito” porque dependiendo de qué botón o qué elemento hacemos clic en “Agregar al carrito” on va a tener un valor diferente. La forma en que voy a hacer esto es en lugar de agregarlo al HTML interno voy a crear un elemento y luego anexarlo al DOM. El motivo por el que voy a hacerlo de esta manera es para que pueda adjuntarle un oyente de eventos antes de que lo añada al DOM. Lo que voy a hacer es crear un elemento para el botón. Sólo va a ser botón y luego por supuesto que tengo que guardar eso en alguna parte, así que voy a guardar eso en el botón constante llamado. Voy a configurar el HTML interno del botón para agregar al carrito y luego voy a agregar un oyente de eventos. En realidad, vamos a comentar eso por ahora. Vuelve a ella en un segundo. Sólo voy a anexar eso para agregar documento primero. Pulsa “Guardar” en eso, refresca aquí y puedes ver tenemos nuestros botones Agregar al carrito y su estilo, igual que en nuestro ejemplo por el CSS que ya hemos llegado allí. Ahora para que esto funcione, necesitamos poder saber cuál es el nombre y el id del producto que estamos agregando al carrito? Porque esto actualmente no está haciendo nada, y ahí es donde vamos a pasar en el id Pero también necesitamos saber cuál es el precio de cada producto, por lo que podemos añadir eso a nuestra mesa de carrito también. Vamos a pasar en id y precio. Vamos a crear atributos para ellos también. Voy a empezar dentro del componente, y digo this.id es igual a this.getAttribute, no animaciones atributos, id, y luego this.price, this.getAttribute price. Entonces voy a ir a los elementos aquí. Agreguemos un id para cada uno. El primero vamos a hacer 1, 2, 3, y 4. Sólo hay productos completos, por lo que sólo necesitamos identificaciones simples. Entonces voy a sumar el precio. Vamos a mantenerlo simple y hacer que cada uno de ellos $10. Simplemente pasaremos estos como dígitos ahora y los convertiremos en números enteros o flotadores más tarde. Ahora volviendo a nuestro componente web, esta es la parte donde realmente construimos en alguna funcionalidad y nos complicamos un poco más. Como puedes ver aquí, tengo un EventListener comentada. Lo que quiero hacer antes de construir eso es crear el método que este EventListener va a desencadenar. Fuera del constructor, vamos a crear nuestro propio método llamado AddToCart. En AddToCart, lo que vamos a hacer es construir un objeto con todos los atributos que queremos agregar a un objeto item cart. Voy a crear un objeto const item y deberías ver a qué me refiero con esto muy pronto. Por supuesto voy a agregar una clave de id, y sólo voy a tomar el id que se almacena en este componente web. Voy a cerrar esto para que puedas ver más. Entonces voy a tomar el nombre y eso va a ser igual al nombre tal y como se establece en el componente web. Cantidad siempre va a igualar a uno porque el botón Agregar al carrito sólo va a agregar uno por defecto. Puedes añadir en un selector de cantidad a este elemento más adelante si quisieras como mejora. Pero por ahora, en cualquier momento que haga clic en “Añadir al carrito” sólo va a agregar uno. Voy a arreglar eso al número 1, y luego el precio va a ser esto.precio. Echemos un vistazo. Cuando realmente ejecutamos esto, todo lo que voy a hacer para empezar con sólo para verlo es ejecutar el log de consola, y luego ItemObject, el objeto que acabamos de crear. Aquí arriba en AddVentListener, obviamente voy a buscar el click “Evento”, y luego voy a ejecutar este método addToCart, y luego voy a enlazar esto, que cuando estoy aquí abajo en este método, cada vez que haga referencia a esto, voy a estar haciendo referencia al componente web, no al evento. Golpea “Guardar” en eso, refrescar por aquí. Vamos a abrir nuestra consola, y si hago click en “Añadir al carrito” en el Aceite de Semilla de Cáñamo, se puede ver que envía a través de los datos. Podemos ver que el id del producto es 2, el nombre es Aceite de Semilla de Cáñamo. Estamos agregando uno y el precio de cada uno es de 10. Si lo hago en la Coca Cero Can, obtengo un poquito de datos diferentes. Si lo hago en la Crema Corporal y Pasta de Curry Rojo, se puede ver que consigo un objeto diferente cada vez. Eso es confirmar que estamos enviando a través de un objeto con toda la información que necesitamos. Ahora lo que tenemos que hacer es escribir un poco de lógica con el fin de agregarlo a este array items dentro de nuestro objeto carro. Vayamos por aquí y te mostraré cómo podemos acceder a ese objeto de carro. Porque está en el objeto ventana, podemos escribir window.cart para echarle un vistazo o simplemente podemos escribir carro porque ya estamos en el contexto de ventana. Como se puede ver, no importa de qué manera lo hagamos, podemos ver que tenemos un objeto con una matriz de ítems vacíos. Lo que queremos ver cuando volvamos a emitir eso, después de añadir al carrito, es que tenemos un nuevo elemento en esa matriz de ítems. Eso lo aclararé. Vamos a hacer eso ahora mismo. Voy a comentar ese registro de consola, y lo que tenemos que hacer en la mayoría de los casos es agregar ese objeto simplemente a la matriz de ese elemento. Vamos a hacer window.cart.items.push para agregar ese objeto item a la matriz item, y luego vamos a poner en el objeto item como argumento ahí. Vamos a dar “Guardar” en eso. Refresca por aquí. Si escribo en carro en este momento, se puede ver que tenemos una matriz de artículos que está vacía. Consigamos un poco más específicos y digamos artículos del carrito específicamente. Tenemos una matriz vacía que está clara de ver. Déjame hacer eso una vez más. Tenemos el antes, entonces si hago clic en “Agregar al carrito” y escribimos en cart.items ahora, verás que tenemos un objeto en nuestra matriz, y si miro dentro, es nuestro Aceite de Semilla de Cáñamo con el cantidad de uno. Si hago click en “Añadir al carrito” en Body Cream y luego voy cart.items, ya deberías ver que tenemos dos artículos en nuestra matriz con cada uno de esos productos. Ahora tenemos un tema que no sé si pensaste en esto o no, pero pronto descubrirás que este es un tema. Si agrego otro del mismo producto que ya tenemos en nuestro carrito, digamos de nuevo Aceite de Semilla de Cáñamo, y luego me voy a aquí y voy carrito.artículos, verás tenemos tres artículos en el carrito, y tenemos Aceite de Semilla de Cáñamo dos veces, pero con una cantidad cada uno. Queremos ver un elemento en la matriz para Aceite de Semilla de Cáñamo, pero queremos que este número sea dos. Necesitamos escribir un poco de lógica extra para eso. Volvamos a aquí y utilicemos el método find dentro de JavaScript para averiguar si el elemento ya existe en la matriz. Voy a crear un artículo constante en el carrito. Entonces vamos a buscar window.cart.items, entonces vamos a usar el método encontrar pasando por el ítem. Si el id del elemento es igual al id del objeto del elemento, entonces hemos encontrado una coincidencia, y ese va a ser el objeto. Antes de escribir algo más, vamos a hacer console.log item_in_cart. Debería pasar como indefinido o algún otro valor nulo si realmente puede encontrar algo, pero si encuentra algo, en realidad obtendremos el objeto en sí. Refrescante por aquí. Hagamos clic en “Añadir al carrito” y saldrá como indefinido. Pero si volvemos a hacer clic en “Añadir al carrito”, verás que tenemos ese producto existente ya en el carrito. Si vas cart.items, puedes ver que tenemos el mismo artículo dos veces en el carrito. Tenemos que arreglar esto. Lo que vamos a hacer es ejecutar si item_in_cart, entonces todo lo que queremos hacer es tomar ese artículo que ya está en el carrito y simplemente aumentar su cantidad en uno. Pero si no está en el carro, así que si sale indefinido, por ejemplo, vamos a entonces ejecutar este código aquí abajo para empujar ese artículo al carrito. Vamos a guardar eso y veamos si eso soluciona nuestro problema aquí. Voy a añadir en Aceite de Semilla de Cáñamo, voy a añadir en Crema Corporal. Echemos un vistazo a nuestros artículos de carrito ahora. Tenemos un Aceite de Semilla de Cáñamo y una Crema Corporal. Si vuelvo a añadir uno del mismo producto, el Aceite de Semilla de Cáñamo y luego vamos a echar un vistazo a la carta.items, puedes ver solo tenemos dos artículos en nuestra matriz ahora, y si hago click en ellos, tú puede ver haciendo clic en “Añadir al carrito” en el Aceite de Semilla de Cáñamo, realidad no ha creado un nuevo elemento en nuestra matriz, pero es simplemente aumentar la cantidad de ese artículo existente, que es exactamente lo que queremos. Regresando aquí, esa es esencialmente toda la funcionalidad que necesitamos, específicamente desde el elemento producto. Sólo para resumir en este punto antes de seguir adelante, hemos creado un elemento de producto componente web. Hemos pasado en cuatro parámetros. Dentro del propio componente web, tenemos una estructura estándar que es común a todos los componentes web del elemento del producto, y una funcionalidad común de AddToCart, que podemos ver aquí mismo. Voy a quitar ese registro de consola porque todo esto está funcionando, y ahora se puede ver, pesar de que no tenemos carta.items visualmente representados en la página todavía, podemos agregar elementos a nuestro carro artículos array. El objeto carro aquí es básicamente nuestro objeto estatal, y lo que vamos a hacer es usar ese objeto carro para crear nuestra tabla de artículos de carro en el siguiente video. Según lo prometido, voy a cometer este código y descartaré. Probablemente debería haber puesto eso en el get ignore. Unstage, entra aquí, descarta eso, y luego voy a comprometer nuestros cambios a index.html, index.js, y luego, por supuesto, la creación de product.js. Voy a poner en escena todos esos cambios y agregaré el mensaje de confirmación, crearé elemento de producto componente web. Barrido. Voy a pegar commit en eso, nuevo, descartar esos cambios. Voy a romper esto en otro video. En el siguiente video, veremos el componente de artículos del carrito. 11. Componentes web en la práctica, parte 2: Muy bien, chicos. En el último video, configuramos un index.js, que tiene nuestros objetos cortados con la matriz items, y aprendimos cómo podemos poblar esa matriz de artículos a través de este elemento de producto que creamos en el video anterior, y obviamente, eso tiene un componente visual a ella también. Contamos con cada uno de estos productos elementos con estos botones de añadir al carrito. Si hago clic en alguno de estos botones de añadir al carrito, se actualizará nuestro cart.items que tenemos aquí, pero eso no está realmente representado visualmente en la pantalla hasta el momento. Eso es lo que haremos en este video. Vamos a crear un nuevo componente llamado artículos de carrito. Hagámoslo ahora mismo. Vamos a entrar en nuestra carpeta JS, crear un nuevo archivo llamado cart-items.js. Vamos a conseguir que nuestro código de calderas de componentes vaya aquí. Artículos del carrito es lo que voy a llamarlo, y vamos a extender la clase de elemento HTML. Ahí vamos. Estoy tentado aquí solo a escribir elementos personalizados definidos, pero recuerda que estamos usando módulos ES. En lugar de eso, lo que voy a hacer es exportar artículos del carrito, y luego voy a hacer mi método definido aquí en el archivo de índice. Definir artículos de carrito, artículos del carrito aquí. Lo y he aquí, el código de Visual Studio sabe lo que estoy tratando de importar y automáticamente agrega la declaración de entrada aquí arriba. Pero si tu editor de código no hace eso por cualquier razón, simplemente puedes escribir este código. Es el mismo formato que el que teníamos antes. Dulce. Para conseguir este componente de artículos de carrito en un documento, simplemente voy a ir por aquí dentro de nuestro contenedor, por lo que todo está contenido, voy a agregar en nuestro componente web personalizado de artículos del carrito. Se va a poner automáticamente en la etiqueta de cierre ahí. Ahora, si refresco mi página por aquí y no hay errores, puedo decir confiablemente que tenemos eso en nuestro documento aquí. Si entro aquí, puedes ver que tenemos nuestro componente web de artículos de carrito vacíos aquí. En realidad vamos a agregarle algunas cosas. Cerremos productos por el momento. Vamos a pasar a dentro de nuestra definición de clase aquí. Obviamente, como siempre, vamos a necesitar nuestro constructor, y dentro de nuestro constructor vamos a poner en nuestro super método. Ahora, a diferencia de todos los otros componentes que hemos hecho en el pasado, realidad lo voy a dejar ahí para el método constructor. Voy a poner todo nuestro renderizado dentro de otra función llamada render. Ahora, ¿por qué haría eso? El motivo por el cual es porque cuando agregamos un nuevo producto al carrito a través de este elemento de producto, vamos a necesitar renderizar por primera vez o volver a renderizar nuestra tabla de artículos del carrito. Va a ser útil tener nuestra función de render aquí para que con eso podamos volver a renderizar siempre que lo necesitemos. Todo el código dentro de esta función de render no se ejecutará cuando el componente de artículos de carro esté incluido en la página, como lo tenemos aquí, se va a ejecutar realmente una vez que específicamente le pedimos que se renderice. Esto va a ser mucho código y no voy a ir súper profundo en todo ello, pero voy a explicar a medida que voy. Lo que voy a hacer es crear un punto de partida para este componente de artículos de carrito. Voy a establecer el HTML interno a nada cuando ejecutemos render. Ahora, la intención de esto es cuando ejecutamos render en el futuro, necesitamos borrar el contenido que teníamos antes, lo contrario podríamos tener algo del antiguo HTML interno dentro nuestro componente cuando tienen que volver a renderizar el carrito. Entonces lo que voy a hacer es construir un HTML usando document create, el segundo método que vimos en el video anterior en tres formas de crear HTML dentro de nuestro componente web. Olvidé poner aquí el nombre de la variable. Voy a llamar a este contenedor de mesa. Entonces voy a agregar la clase de contenedor de tabla a este contenedor de tabla div, y luego el segundo elemento que voy a crear se llama tabla. Esta es nuestra tabla real de artículos de carrito. ir a crear un elemento de tabla, asígnelo a la constante de la tabla aquí. Entonces lo que vamos a hacer es que vamos a recorrer todos los artículos del carrito. Voy a correr un cuatro cada uno en estos. Voy a tener dos argumentos aquí, uno para el elemento en sí para que sea el elemento en sí, y luego el segundo será el índice. Déjame volver a eso en un segundo antes de entrar en ese código profundo. Lo que voy a hacer es table_container. Lo que quiero hacer es anexar nuestra tabla a ese contenedor de tabla, y luego vamos a anexar contenedor de la tabla a nuestro componente web. Aquí está pasando un poco, pero ten cuidado conmigo. Lo que estamos haciendo es que básicamente creamos si guardo y luego refresco aquí. Ahora, en realidad no es renderizado porque, recuerda, esto está en el método render, no está en el constructor como teníamos antes. Lo que vamos a tener que hacer es ejecutar algún código para encontrar el componente web que estamos buscando, que es cart-items, y luego ejecutar el método render en eso. Si vuelvo aquí ahora, se puede ver que dentro de nuestros artículos de carro, vamos a tener un div con la clase de contenedor de mesa y dentro vamos a tener la mesa. Eso es lo que estamos haciendo aquí, estamos creando esta estructura HTML. Ahora, lo que vamos a hacer es por cada ítem de la matriz, vamos a sumar. Voy a agarrar el HTML interno, y voy a usar el plus igual para anexar a nuestra cadena aquí, vamos a abrir esto, y voy a agregar en una fila por cada artículo del carrito en nuestro cart.items array. Veamos esto en acción. Si pego “Guardar” y voy por aquí, y volvamos a ejecutar ese método render, volver a entrar aquí, encontrar nuestro contenedor de mesa de artículos de carro y dentro de nuestra mesa, verás que no hay filas en la tabla todavía, pero eso es porque en realidad no tenemos nada en nuestra matriz cart.items. Si voy cart.items, no hay nada ahí dentro. Si tuviera que añadir, digamos, dos ítems a nuestra matriz, echemos un vistazo ahora, cart.items. Definitivamente tenemos dos artículos en nuestra matriz ahora. Si iba a ejecutar render en artículos del carro, volver a la cabeza a elementos aquí, ir dentro de nuestra mesa, se puede ver que tenemos dos filas. Ahora, obviamente, necesitamos poblar cada una de estas filas con los datos de cada uno de esos artículos del carrito, y eso es lo que vamos a hacer en este momento. De nuevo, va a haber bastante código aquí pero ten cuidado conmigo. Necesitamos tres celdas de mesa. En la primera celda de tabla, vamos a poner el nombre del artículo. Entonces por supuesto que tenemos acceso a cada ítem a medida que lo recorremos, porque eso es lo que hemos puesto aquí. Voy a decir nombre del artículo. Entonces aquí vamos a tener una entrada de cantidad. Llegaremos a eso un poco más tarde. En éste, vamos a tener $sign y luego vamos a tener nuestro artículo dot precio. Arreglaremos esto en un segundo porque este tiene que ser el precio de línea. Entonces si la cantidad es mayor que una, entonces necesitamos actualizar esto. Entonces lo que voy a hacer es sólo un poco de formateo. El primer td. Quiero que el texto esté alineado a la izquierda, pero eso es por defecto, así que no voy a cambiar nada ahí. En el segundo, voy a hacer que el texto se alinee al centro. Entonces el último voy a establecer el texto alinear a la derecha. Ahora si pego “Guardar” en esto, creo que automáticamente se recarga caliente de todos modos. Golpeé “Añadir al carrito” en dos de estos botones. Entonces ejecuto la función render. Puedes ver aquí tenemos los inicios de nuestra mesa. Tenemos el nombre del producto que está en el recorte y el precio. Pero por supuesto, si vuelvo a golpear éste, sólo tenemos dos ítems en la matriz. No actualiza la cantidad ni el precio de línea. Entonces antes de que realmente creamos la cantidad seleccionada aquí, solo puedo poner en la cantidad del artículo. Mientras estamos aquí, vamos a arreglar este precio, el precio de línea. Llamemos a este precio de línea. Eso va a ser igual a asegurarnos de poner esto dentro del bucle. El precio de línea va a ser igual a los tiempos del precio del punto del artículo por la cantidad del artículo. Le pegaré a “Guardar” en eso. Refresca aquí, agreguemos algunos artículos al carrito. Acabo de presionar “Añadir al carrito” en aceite de semilla de cáñamo, luego en crema corporal, luego volver a aceite de semilla de cáñamo de nuevo, por lo que deberíamos ver dos artículos en nuestra matriz. Si voy aquí abajo, se puede ver que nuestra selección se ha salvado. Si corremos render, podemos ver que está apareciendo en nuestra mesa aquí abajo. Ahora claro, cada vez que tenemos que ejecutar la función render nosotros mismos, obviamente no queremos hacer eso. No vamos a esperar que el usuario entre en su consola y sepa qué comando ejecutar. Así que vamos a configurar eso para que se ejecute en nuestro producto dot js. Después de sumar al carrito, así que aquí mismo voy a añadir una línea. Literalmente podemos tomar esta línea y colocarla ahí. Golpea” Guardar” en eso, refresca por aquí. Cada vez que hacemos clic en “Agregar al carrito”, volverá a renderizar el carrito. Esto me molesta un poco. Quiero almacenar este componente web en sus propias variables así que voy a crear una variable para esto. Voy a subir aquí y hacer este punto carrito artículos iguales y luego tomar ese elemento del DOM. Esto me siento como si estuviera un poco más limpio. Nuevamente, no hay que hacerlo de esta manera, pero me gusta un poco mejor. La siguiente parte que voy a hacer antes pasar a codificar la entrada de cantidad es crear el pie de página de tabla. Entonces si lo miro ahora, en realidad no tenemos el total y para eso vamos a crear un pie de página de tabla. Sólo voy a quitar eso ahí. Vamos a entrar en artículos de carrito dot js. Ya estamos ahí. Entonces después de este código, lo que voy a hacer es crear un nuevo elemento llamado documento pie de página crea elemento. Esto va a ser un div. Entonces también voy a tener que averiguar el total del carrito. Entonces voy a tener que usar un poco de un método complicado aquí, ventana dot cart dot items, y luego ejecutar el método reduce en él para contabilizar todo. Por lo que el ítem total, si esto te confunde, solo estudia el método reducido, pero es una manera para nosotros de sumar todos los valores hasta crear un total. Lo que voy a hacer es porque los precios van a pasar como cadenas, porque los hemos puesto a través como una cadena en nuestro HTML aquí, sólo tenemos que pasarlos a enteros. Ahora, podríamos querer pasar estos a flotadores si tuviéramos valores decimales pero para este proyecto, no vamos a tener ningún valor decimal. El monto más bajo va a ser uno y va a subir en uno, así que nada va a ser 2.75 dólares ni nada de eso. Sólo vamos a mantenerlo simple. Van a ser $10 o $20. En realidad, todo en este proyecto va a ser $10 así que lo estamos manteniendo muy sencillo. Pero para que lo sepas, es posible que necesites cambiar esto. Pero para nuestros fines, todo va a ser un entero, así que podemos hacer pars int. Déjame abrir esto un poco más para ti. Entonces en el pars int, vamos a tomar el total add item dot price times by the item dot quantity, que es por supuesto el precio de línea, que calculamos antes aquí arriba. En el segundo parámetro vamos a poner a través de cero. Entonces lo que podemos hacer es establecer el HTML interno del pie de página en, pongamos aquí algún código HTML. Vamos a poner en otra mesa, que se va a alinear con la primera mesa. Va a darle a esto una clase de pie de carro. Entonces vamos a poner en una nueva fila. Entonces aquí, vamos a poner en una celda, que sólo va a tener la palabra total. Entonces vamos a poner en otra celda para el total en sí. Voy a poner en el estilo de texto, alinear. Se alinea con el precio de línea por aquí. Entonces aquí podemos poner nuestro valor dinámico. Entonces voy a poner en un signo $ real primero, y luego $ firmar llaves rizadas para poner en nuestro carrito total, que acabamos de calcular. Entonces aquí abajo, este punto anexar pie de página hijo. Le pegaré a “Guardar” en eso y luego nos refrescaremos por aquí. Si hago clic en “Agregar al carrito”, puedes ver que tenemos nuestro total apareciendo aquí. Todavía no puedo reducir las cantidades, pero se puede ver que al menos podemos añadir artículos al carrito. Nuestra tabla de artículos de carrito se está actualizando, completa con el total para que apenas alrededor nos cubra para los artículos del carrito, componentes de mesa aquí. El último componente va a ser el componente de entrada de cantidad, que se va a anidar dentro del componente de elementos curt. Voy a romper eso en su propio video, así que lo cubriremos en el siguiente video. Entonces haremos nuestras modificaciones finales para completar este proyecto. Los atraparé en la siguiente. 12. Componentes web en la práctica, parte 3: En este tercero y ojalá el video final esta serie en el que estamos construyendo esta funcionalidad de carrito de compras personalizado, voy a codificar hasta la entrada de cantidad. Ahora una cosa que olvidé hacer antes de cerrar el último video fue cometer este código para ustedes, así que voy a hacer eso ahora. Simplemente descartaré esta tienda DS de nuevo y solo echando un vistazo a los cambios aquí. Siempre me gusta hacer esto antes de comprometerme. Voy a escenificar todos esos y el mensaje commit será crear ítems cortados. Eso está comprometido. Descarta esa otra vez. Permítanme cerrar algunos de estos. Probablemente tenga que abrirlas de nuevo, pero aquí está pasando demasiado. Vamos a entrar en nuestra carpeta js aquí y crear el componente de entrada de cantidad. Nuevamente, comenzando con el código de calderas, ustedes deberían estar bastante familiarizados con esto por ahora. La entrada de cantidad extiende elementos HTML. Entonces lo vamos a exportar de inmediato. Exportar valor predeterminado, entrada de cantidad, luego entrar en index.js. Voy a escribir mis elementos personalizados define el método primero porque sé que va a importarlo automáticamente. Llamemos a esto con el nombre extendido cantidad-entrada. Magic VS Code ha puesto esa declaración de entrada ahí para nosotros para que pueda cerrar eso hacia abajo. Para este elemento en particular, lo que voy a hacer es básicamente construirlo todo en el constructor, como hemos visto anteriormente en esta clase. preguntando de Aquí va a haber bastante código y si te estás dónde sacé todas las ideas para esto, en realidad tomé el tema del amanecer de Shopify como inspiración. Gran parte de este código está inspirado en el mismo código dentro este componente dentro del tema Shopify dawn. Si quieres hacer referencia a esto en contra de eso, o preguntarte de dónde viene mi proceso de pensamiento, puedes echar un vistazo a ese tema. Como de costumbre, vamos a poner aquí el super método y luego lo que voy a hacer es, vamos a escribir todo el HTML dentro del cart-items.js aquí. Desplazarse aquí, todo lo que estamos haciendo hasta ahora es solo escribir la cantidad del artículo tal y como está en esta segunda columna aquí, pero por supuesto que no podemos actualizarlo no hay entrada ahí. Vamos a reemplazar esto por nuestro nuevo elemento personalizado, entrada de cantidad para la etiqueta de cierre. Voy a crear todo el HTML interno dentro de las etiquetas mismas. No hicimos esto obviamente por el elemento producto aquí, porque no queríamos tener que escribirlo cuatro veces diferentes. Aquí, en el caso de la entrada de cantidad, vamos a estar escribiéndola cada vez que haya una fila en la tabla, y cada fila va a verse prácticamente igual. La única diferencia son los datos que vienen a través del ítem. Podemos colocarlo aquí y todavía va a ser código DRY. Aquí, sólo voy a poner una clase de cantidad. Si me ves escribiendo clases como esta, está relacionada con el CSS, así que no te preocupes demasiado por las clases. Entonces vamos a crear nuestros dos botones, nuestro botón menos, nuestra propia entrada. Obviamente hay muchas más cosas que hay que ir aquí, pero yo sólo voy a empezar con la estructura básica primero. Tenemos botón de entrada. Solo echemos un vistazo a cómo se ve eso. Se puede ver la estructura básica ahí, pero por supuesto que vamos a necesitar poner el menos en entre esas etiquetas de botón y luego el plus in-between estas etiquetas de botón. Para los atributos, vamos a darle una clase, vamos a ponerla en ambos botones aquí, clase de cantidad__button. Ir a cerrar esto para que podamos ver mejor. Botón de tipo. Podemos poner eso en ambos, teclear botón, y luego el nombre se va a basar de donde sea menos o más. Me escaparé de eso y luego pondré menos en el primero y luego más en el segundo. Vamos a dar “Guardar” en eso y veamos cómo se ve eso hasta ahora. Parece que tenemos un hit “Guardar” en eso. De todos modos no debería ser tan relevante. Golpea “Añadir al carrito” y como puedes ver ahora, tenemos nuestros estilos viniendo por el plus y los menos. Necesitamos agregar algún código aquí dentro de nuestras etiquetas de entrada aquí. Agreguemos algunos atributos. Queremos que el tipo sea números para que la gente use carrito inserte texto aquí aparte de dígitos. El valor va a ser igual al item.quantity. El mínimo va a ser cero. No queremos valores negativos. Vamos a darle un ID y el ID va a empezar con cantidad y luego vamos a poner un guión y luego usar el índice para diferenciar cada una de las entradas. Entonces voy a poner aquí también un índice de datos, que va a ser lo mismo. Vamos a usar el I como índice de datos. Le pegaré a “Guardar” en eso. Refresca aquí, haz clic en “Agregar al carrito” y como puedes ver, esto parece que está funcionando. Lo único que no está funcionando es no podemos sumar y restar. Si cambio esto a dos, en realidad no va a cambiar los dos. Si cambio esto a cero, en realidad no cambia el cero. Ahí es donde necesitamos empezar a codificar realmente nuestra entrada de cantidad aquí dentro de su definición de clase. Vamos a configurar algunas cosas en nuestro constructor. Quiero primero traer la entrada a su propia variable. Vamos a encontrar eso dentro del DOM, dentro de nuestro componente web. Entonces lo que voy a hacer es crear un onButtonClick, que va a ser la devolución de llamada para nuestro EventListener. Voy a añadir en el evento como el único parámetro. Voy a evitar cualquier comportamiento predeterminado, y luego voy a escribir alguna lógica aquí para que esto funcione. Lo primero que quiero hacer es agarrar el valor anterior, el valor antes de cambiarlo, y eso sólo va a ser igual al valor de entrada en el momento de esta ejecución. This.input representa el elemento de entrada en sí, y por supuesto podemos agarrar el valor de cualquier entrada con solo mirar su propiedad de valor de punto. Se va a agarrar el valor antes de cambiarlo y luego vamos a echar un vistazo al evento y mirar los objetivos del evento. El objetivo del evento en esta instancia va a ser el botón en el que hacemos clic. Entonces vamos a mirar el nombre del objetivo del evento, es decir, el botón y si es plus, solo estamos usando aquí un operador ternario, para aumentar para correr de paso hacia arriba en la entrada. Step-up es solo un método que nos permite aumentar el valor de esta entrada por uno. Si no es plus, lo que significa que definitivamente es menos porque solo hay dos opciones, vamos a correr paso abajo en su lugar. Ahora si pego “Guardar” en eso, ahora que tenemos aquí nuestro manejador de eventos, en realidad vamos a adjuntar eso a todos los botones. Para esto porque hay múltiples botones, vamos a usar un QuerySelectorAll para cada botón, que está en los dos y al final pero aún necesitamos usar QuerySelectorAll. Eso nos va a dar una matriz y luego necesitamos hacer un bucle a través de ellos. Para cada botón, vamos a agregar un EventListener de click. Si se hace clic en el botón, entonces vamos a ejecutar ese manejador de eventos al pulsar el botón. Al igual que antes, vamos a enlazar esto para que esto represente el componente web y no el evento. Quita ahí ese punto y coma y póngalo ahí. Si pego “Guardar ahora” y refresco por aquí, haga clic en “Agregar al carrito”, puedo conseguir que esto dé un paso arriba y abajo, pero ¿qué no está pasando? En realidad, si presiono menos, va a bajar. Eso no es muy útil, ¿verdad? Creo que eso probablemente esté relacionado con este error tipográfico aquí. Esto no es una comparación, esto es una tarea, así que permítanme hacer de eso una asignación adecuada. Volvamos por aquí, haga clic en “Agregar al carrito”. Ahora, si presiono, debería funcionar. Ahora la cosa es con esto es, el valor dentro de esta entrada va subiendo y bajando con estas pulsaciones de botón, lo cual es bueno, pero en realidad no está cambiando el valor en nuestros datos estructura. Digamos que pongo esto hasta siete, y luego vamos en realidad ir a nuestra matriz de artículos del carro y echar un vistazo en el interior, se puede ver que la cantidad sigue siendo una. Podemos aumentar la cantidad presionando aquí el añadir al carrito y como se puede ver, se actualiza a dos ahora. Entonces si entro en artículos del carrito, puedo ir aquí y es la cantidad 2, pero poner esto arriba y abajo no cambia realmente nada. Vamos a arreglar eso ahora mismo. La forma en que voy a arreglar eso es mediante el uso de un evento personalizado. Ahora, ¿por qué voy a usar aquí un evento personalizado? Bueno, quiero desencadenar un evento de cambio en la cantidad. Lo que voy a hacer es que voy a pasar por la línea del artículo que quiero cambiar y su nueva cantidad a un método, y luego ese método va a actualizar cart.items. Ahora podemos poner este método dentro de entrada de cantidad, pero creo que tiene más sentido ponerlo en cart-items porque literalmente está actualizando cart.items, el objeto con el que se relaciona este componente. Voy a ponerlo aquí antes de render. Qué va a hacer este método, lo voy a llamar update quantity. Se va a llevar un índice que se va a relacionar con la línea de ítem aquí. Como puedes ver aquí, estamos bicicleta a través de una matriz y estamos almacenando en la cantidad seleccionar qué número en la matriz es. Puedo utilizar eso para averiguar el número de línea. Entonces el segundo parámetro va a ser el nuevo valor, que solo voy a llamar valor como parámetro. Entonces cuando esto se ejecute con esos dos parámetros, lo que voy a hacer es entonces buscar el ítem a través de su índice, y luego simplemente tomar la cantidad de ese artículo y luego cambiarlo a sea cual sea el valor que pasemos. Entonces cuando eso se actualice, lo que vamos a hacer es volver a renderizar la tabla de artículos del carrito, porque obviamente necesitamos volver a renderizar el precio de línea y necesitamos volver a renderizar el total cuando estemos haciendo estas actualizaciones, por lo que es mejor solo volver a renderizar toda la mesa. Voy a golpear “Guardar” en esto, y entonces lo que voy a hacer es hacer referencia a artículos del carrito. Como vimos antes con el producto, cuando hacemos referencia a artículos del carrito, lo puse en su propia variable primero antes de ejecutar el método aleatorio en ella. Porque vamos a estar ejecutando un método en esto, quiero hacer algo similar, configurar esto en el constructor, así que voy a poner esto aquí arriba. Entonces cuando nos ejecutemos en el botón click, obviamente vamos a estar cambiando el valor de la cantidad. Ahora porque hemos asignado ese componente web a esta variable aquí, puedo ir this.cart items y ejecutar el método en esos componentes web, por lo que puedo hacer actualizar cantidad, y para esto sólo hay que averiguar cuál es el índice. Voy a ir a este índice de conjunto de datos de entrada, por lo que eso me va a permitir acceder a este justo aquí, índice de datos. Eso está disponible en la matriz de conjuntos de datos. Voy a agarrar ese índice. Entonces como segundo argumento, voy a poner esto.input.value. Le pegaré a “Guardar” en eso. Ahora vamos a refrescarnos por aquí. Haga clic en “Agregar al carrito”. Ahora como se puede ver, medida que disminuyo y aumente esto, va a volver a renderizar toda la tabla de artículos del carrito y cambiar el total y el precio de línea. Ahora falta una cosa más aquí, y eso es si cambio esto a dos, no va a cambiar nada. Si vuelvo a esto, lo va a cambiar, pero si pongo en un valor específico, no va a cambiar eso. Permítanme refactorizar este código un poco más. Lo que quiero hacer aquí es que quiero crear un evento personalizado. Ahora recuerda cuando hablamos de eventos personalizados antes, realmente no tenía sentido porque solo estábamos vinculando un click y transformando eso en otro evento personalizado. Pero esta vez tenemos dos formas de cambiar el valor de entrada, es decir, la cantidad en este caso. Podemos establecer un valor de cantidad específico, o podemos usar botones más y menos aquí. Lo que quiero hacer es combinar ambos eventos en su propio evento, que voy a llamar evento de cambio. Eso tiene sentido. Veámoslo en acción. En primer lugar, voy a crear este evento personalizado. Voy a ir esto.changed evento va a ser, como vimos anteriormente con la creación de eventos personalizados, creamos un nuevo evento, le damos un nombre, y luego esta vez quiero agregar un objeto JavaScript para burbujeante. Quiero poner burbujas a verdad. Lo que esto va a hacer es que se va a registrar un evento de cambio en el componente web de padres también, porque quiero que se registre aquí. Entonces aquí voy a crear un oyente de eventos para el evento de cambio en estos componentes web en particular. Voy a poner en cambio aquí, crear una función aquí. Voy a agarrar la entrada. Va a ser el evento de cambio aquí. Entonces lo que voy a hacer es que voy a poner aquí la cantidad de actualización. En lugar de tener que ejecutar este método cuando ejecutamos el botón click event handler, y luego también el manejador de eventos para cuando cambiamos el elemento explícitamente, como lo hicimos antes, como esto, voy a despachar este evento de cambio tanto en el botón click como en ese cambio de entrada. Déjame apenas escribir aquí esto, y voy a cavar en la entrada porque necesitamos usar algunos de sus atributos allí. Entonces voy a despachar este evento personalizado, por lo que este evento de cambio. Entonces porque estamos mirando la entrada específica, en lugar de no tener nada aquí lo que puedo hacer es pasar por el evento, y luego en lugar de mirar esta entrada, puedo crear una referencia a la aquí basada en el objetivo actual del evento. Lo siento, se me olvidó poner ahí la asignación. Entonces podemos quitar este punto de cada uno de estos. Vamos a dar “Guardar” en eso y veamos si eso funciona. Voy a abrir mi consola por si acaso haya errores. Añadir al carrito. Pon esto, baja esto. No está funcionando porque estamos comprobando los eventos en el componente web no en la entrada. Lo que voy a hacer es solo agregar un parámetro extra aquí con un objeto JavaScript, y voy a poner burbujas a true. De esa manera, el evento de cambio va a burbujear hasta el propio componente de entrada de cantidad. Vamos a golpear “Guardar” en eso, refrescarnos por aquí, y veamos si esto funciona ahora. No se pueden establecer propiedades de la cantidad de configuración indefinida, vamos a echar un vistazo. Echemos un vistazo a lo que está pasando por aquí, entrada de registro de consola. Echemos un vistazo. Eso es pasar por el propio componente web. Eso debe ser porque estamos burbujeando hasta el componente web que está desencadenando el cambio y luego el objetivo actual del evento en esa instancia se convierte en el propio componente web no en la entrada. Podemos arreglarlo con solo usar nuestra consulta seleccionada para entrar y seleccionar esa entrada. Vamos a golpear “Guardar” en eso, refrescar por aquí, golpear “Añadir al carrito”, y luego tenemos el mismo resultado que teníamos antes. Esto es realmente actualizar nuestras cantidades y actualizar nuestro carrito también. Como se puede ver, esto no está funcionando. Permítanme simplemente cambiar esto a dos y luego golpear “Tab”. Como se puede ver, eso es cambiarlo al valor explícito. Como se puede ver, porque el cambio ya es un evento sobre ese insumo, también estamos aprovechando el evento existente que se dispararía cuando lo cambiemos explícitamente. Básicamente estamos agregando nuestro botón click en el evento de cambio. Esto es algo que sucede automáticamente, ni siquiera tenemos que registrar un evento de cambio cuando cambiamos este valor explícitamente, esto simplemente sucede automáticamente. Este es un buen ejemplo de cómo podemos etiquetar en un evento personalizado en algo que ya existe. Ahora sólo para limpiar esto, tenemos este valor anterior aquí. Se supone que si hacemos clic en un botón estamos cambiando un valor, pero sólo para estar seguro voy a añadir aquí una declaración if. Sólo vamos a comprobar si el valor anterior no es igual al nuevo valor. Si guardo, refresco, debemos obtener el mismo resultado que hacemos. Eso es sólo un cheque extra. Eso es básicamente todo chicos. Tenemos nuestros tres componentes web aquí. Tenemos nuestro elemento producto, y si hago clic en “Agregar al carrito” en cualquiera de estos, va a interactuar con nuestro componente de artículos de carrito. Puedo utilizar estos insumos de cantidad para cambiar los precios aquí. En realidad una cosa que no hicimos es si golpea cero queremos quitar eso, y si el total hit cero queremos quitar por completo la mesa. Pensé que habíamos terminado pero sólo nos queda una cosa más por hacer, es por eso que siempre debes jugar con tus proyectos y ver. Vamos a entrar en cartitems.js, y vamos a escribir en algún código extra aquí. Voy a desplazarse hacia abajo hasta el fondo. Lo primero que voy a hacer es si el total del carrito es cero, bueno, en realidad voy a hacer lo inverso. Si el total del carrito no es cero, entonces vamos a renderizar el pie de página. Pero si el total del carrito es cero, entonces este código no se ejecutará en absoluto, lo que significa que no tendremos un pie de carro cuando se ejecute esta función render. Ahorraré en eso. Entonces lo que también voy a hacer es pondré un cheque similar aquí arriba. Justo después del precio de línea aquí, no agregaré la línea a la tabla a menos que la cantidad del artículo sea mayor que cero. Si no es cero, entonces vamos a ejecutar este código, así que agarra eso, y ponlo aquí. Golpea “Guardar” en eso. Ahora cuando agregamos algo al carrito, aumentar su cantidad, pero luego volver a cero, eso eliminará eso. Digamos que tenemos varios aquí y quitamos todos uno de ellos del carro, entonces toda la mesa del carro no desaparece, es sólo esa línea. Podemos sumar todos ellos, quitar algunos de ellos, aumentar la cantidad. Si esta fuera una app en pleno funcionamiento con funcionalidades de checkout como reales habilitadas, podríamos tener aquí un botón que envíe esa matriz de carrito a una página de checkout, y luego el usuario podría para completar ese orden. Eso concluye este pequeño proyecto de clase. Permítanme simplemente comprometer este código antes de que me olvide. Nuevamente, descartando la Tienda DS. Echemos un vistazo rápido a lo que cambiamos aquí. Todo se ve bien. Si detectas algún error con cualquiera de esto, solo avísame. Comentarios a continuación pero voy a escenificar todos esos y luego completar el proyecto con entrada de cantidad. Descartaré esta otra vez. Eso es más o menos chicos. Tendré este código en GitHub para ti. Simplemente búscalo en mi página de GitHub, que es github.com/christopherdodd. Déjame deshacerme de esto. Consulta mis repositorios, mira si puedes encontrarlo ahí dentro. Cualquier pregunta. Déjalos en los comentarios a continuación. Espero que hayas disfrutado de esta práctica aplicación de usar Componentes Web. Ojalá en esta clase, pareciendo que hemos empezado con la teoría y hemos entrado en lo práctico, puede empezar a solidificar lo que hace Web Components y por qué es importante. Te veré en el siguiente video donde concluiremos la clase, y te hablaré sobre cómo puedes extender este proyecto de clase aún más si quieres. Gracias por verlo, te veré en el próximo video. 13. Conclusión: Esto concluye nuestra clase sobre componentes web. Para tu proyecto de clase, te animo a crear tu propio componente web en pleno funcionamiento. Para inspirarte, puedes tomar lo que hemos hecho hasta ahora en esta clase con el ejemplo de e-commerce y agregar funcionalidades adicionales como filtrado de productos o la selección de varianza. Como siempre, si tienes alguna pregunta o inquietud, deja un comentario en el cuadro de discusión a continuación, y haré todo lo posible para apuntarte en la dirección correcta. Gracias como siempre por ver y espero volver a verte en algunos de mis otros cursos.