No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Template

8/22
Recursos

La API template nos permite conectar un web component de forma m谩s profesional y organizada. Tambi茅n nos ayuda a clonar los elementos f谩cilmente. Como vimos en la clase anterior, el elemento no se clonaba, sino que se pasaba de etiqueta en etiqueta hasta la 煤ltima en ser renderizada.

La etiqueta <template>

Template es una etiqueta que nos sirve como contenedor de c贸digo. Todo lo que escribamos adentro de esta etiqueta no se va a renderizar, sino que hay que activarlo mediante JavaScript. El profesor, sin embargo, no muestra cu谩l es dicho proceso y procede a utilizar una forma distinta. En el siguiente enlace vas a ver c贸mo se activa desde JS.

Escribir y activar el c贸digo dentro de la clase

De esta forma estamos armando toda la estructura HTML dentro de JavaScript, pero insert谩ndola en la clase y fraccionando el HTML y CSS para m谩s placer.

En este caso, creamos la clase, con su extensi贸n y constructor, luego creamos un m茅todo que contendr谩 la estructura HTML (getElement). Adentro insertamos la variable template que contiene la estructura.

getTemplate() {
        const template = document.createElement('template');
       	template.innerHTML = `
		...(codigo HTML)
	`
}

C贸mo clonar Elementos

Para clonar el c贸digo debemos indicar mediante el m茅todo cloneNode que se puede clonar. Para eso invocamos el contenido de getTemplate y lo anidamos a la clase (que luego al ser invocada en el HTML se convierte en la etiqueta misma)

render() { this.appendChild(this.getTemplate().content.cloneNode(true)) }

Paso final

Invocamos el render

render() { this.appendChild(this.getTemplate().content.cloneNode(true)) }
	`
}
connectedCallback() { this.render(); }

Contribuci贸n creada con los aportes de: Nazareno Aznar Altamiranda.

Aportes 20

Preguntas 10

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Basicamente la API Template nos permite conectar un web component de forma m谩s profesional y organizada. Tambi茅n nos ayuda a clonar los elementos facilmente (Ya que como lo hicimos en la clase anterior el elemento no se clonaba, sino que se pasaba de etiqueta en etiqueta hasta la ultima en ser renderizada)

La etiqueta <template>

Es una etiqueta que nos sirve como contenedor de c贸digo. Todo lo que escribamos adentro de esta etiqueta no se va a renderizar , sino que hay que activarlo mediante Javascript. El profesor sin embargo no muestra cual es dicho proceso y procede a utilizar una forma distinta. En el siguiente enlace vas a ver c贸mo se activa desde JS:

Escribir y activar el c贸digo dentro de la clase

De esta forma estamos armando toda la estructura HTML dentro de Javascript, pero insertandola en la clase y fraccionando el HTML y CSS para m谩s placer.

En este caso, creamos la clase, con su extension y constructor, luego creamos un m茅todo que contendr谩 la estructura HTML (getElement) . Adentro insertamos la variable template que contiene la estructura.

getTemplate() {
        const template = document.createElement('template');
       	template.innerHTML = `
		...(codigo HTML)
	`
}

En otro metodo (getStyles) todo lo que hacemos es retornar un literal string que contiene el c贸digo CSS (si queremos podemos contenerla en una variable, eso es a comodidad del programador)

getStyles() {
        return `...(c贸digo CSS)`
}

y luego al final del c贸digo de getElement la llamamos de esta forma

${this.getStyles()}

Clonar Elementos

Para clonar el c贸digo debemos indicar mediante el m茅todo cloneNode que se puede clonar. Para eso invocamos el contenido de getTemplate, y lo anidamos a la clase (que luego al ser invocada en el HTML se convierte en la etiqueta misma)

render() { this.appendChild(this.getTemplate().content.cloneNode(true)) }

Y FINALMENTE鈥

Invocamos el render

connectedCallback() { this.render(); }

Hola:

Si desean ver como se hace la transici贸n primero pone el color azul y luego cambia al color rojo (minuto 11:50), se podr铆a cambiar en la pesta帽a de network la velocidad de carga de la p谩gina:

Saludos 馃槂

una simple linea pero poderosa

section>h2{Hola mundo!}+div>p{Soy m谩s texto ejemplo}

Hmmm, no v铆 exactamente para qu茅 se us贸 la etiqueta <template> que escribimos en HTML, imagino que se ver谩 en la siguiente clase
.
Por si les interesa, les dejo el c贸digo en mi repo (con ligeros cambios de texto xD)
.
Adicion de templates a los WebComponents

Apuntes y c贸digo con comentarios:

<h4>Template</h4>

Esto es opcional. Pero si adentro de tu componente van a venir muchos elementos que se conviertan en nodos, lo idal ser铆a ocupar templates.

Recuerda: todo lo que est茅 dentro de la etiqueta <Template></Template> NO se va a renderizar de inicio.

Es importante que cloneNode(true) tenga el valor de true porque as铆 podr谩 copiar todos los elementos anidados del HTML.

Podemos meter estilos con JS pero entrar谩n en conclicto con otros estilos, pero para esto usaremos ShadowDOM.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Custom Elements</title>
</head>
<body>

  <template>
    <h2>Hola desde h2 y template</h2>
    <div>
      <p>Soy m谩s texto dentro de template</p>
    </div>
  </template>

  <my-element></my-element> <!!---Esto viene de JS en customElements.define()-->

  <script type="module" src="my-element.js"></script>

</body>
</html>
class myElement extends HTMLElement {
  constructor(){
    super(); //* Obtenemos acceso a todos los elementos y m茅todos de la clase que extendemos (heredamos)
  }

  getTemplate(){ //*Esto ser谩 puro HTML
    const template = document.createElement('template');
    template.innerHTML = `
      <section>
        <h2>Hola gente desde getTemplate()</h2>
        <div>
          <p>Soy un p谩rrafo</p>
        </div>
      </section>
      ${this.getStyles()} //*Aplicamos los estilos
    `;
    return template;
  }

  getStyles(){ //*Esto ser谩 puro CSS
    return `
    <style>
      h2{
        color:red;
      }
    </style>
    `;
  }

  render(){
    this.append(this.getTemplate().content.cloneNode(true));
    //*Es importante que `cloneNode(true)` tenga el valor de true porque as铆 podr谩 copiar todos los elementos anidados del HTML
  }

  //*Esto es lo que agregar谩 cosas al DOM
  connectedCallback(){
    this.render();
  }
}

customElements.define('my-element' , myElement); //* Definimos que la clase se va a convertir en una etiqueta

para los que no entendieron lo de 鈥渢emplate鈥.

lo que pasa es que solo la etiqueta 鈥渢emplate鈥 tiene la propiedad 鈥渃ontent鈥 con la que puedes hacer el 鈥渃loneNode(true)鈥.


this.getTemplate().content.cloneNode(true)

aqu铆 NO esta clonando de la etiqueta template que creo en el html, esta clonando el innerHTML de la etiqueta 鈥渢emplate鈥 que cre贸 con 鈥渄ocument.createElement(鈥渢emplate鈥)鈥, de hecho si borran la etiqueta template del html ver谩n que no efecta en nada.


const template = document.createElement("template");

a continuaci贸n lo que hacer es definir un 鈥渋nnerHTML鈥 para esa etiqueta 鈥渢emplate鈥 que cre贸 en la linea anterior.


const template = document.createElement("template"); // solo la etiqueta template tiene la propiedad "content"
        template.innerHTML = `
            <section>
                <h2>a</h2>
                <div>
                    <p>x</p>
                </div>
            </section>
        `
        return template;

luego en 鈥渞ender()鈥 sucede la magia, si en render ustedes ponen 鈥渢his.appendChild(this.getTemplate())鈥 ver谩n que les aparece una etiquete 鈥渢emplate鈥 dentro de 鈥渕y-element鈥

js


this.appendChild(this.getTemplate()

html


    <my-element>
        <template></template>
    </my-element>

sin embargo si ponen " this.appendChild(this.getTemplate().content.cloneNode(true))", ver谩n que les aparece solamente lo que definieron en el 鈥渋nnerHTML鈥, tal que:

js


render(){     this.appendChild(this.getTemplate().content.cloneNode(true))
}

html


    <my-element>
        <section>
            <h2>a</h2>
            <div>
                <p>x</p>
            </div>
        </section>
    </my-element>

y esto solo es posible hacerlo con la etiqueta 鈥渢emplate鈥 ya que dentro de otras etiquetas no existe la propiedad 鈥渃ontent鈥

No entendi muy bien su uso.
Pienso que tiene que ver mas con optimizacion entonces 馃
Al usar <Template> se crea un Document Fragment el cual no se renderiza, aqui entonces podemos usar innerHTML para definir la estructura HTML del template, dicho template (fragment) tiene un atributo de solo lectura que es content, el cual podemos clonar con cloneNode(true), este metodo recibe un parametro booleano que indica si el clonado sera profundo o no. Al clonarlo estamos transformando el string del template a nodos reales (elementos de HTML) que luego podemos insertar al DOM con append.
De esta forma nosotros solo le pasamos un solo Nodo con sus nodos hijos, en lugar de un innerHTML que el navegador tenga que traducir a nodos, lo cual deriva en mas seguridad y optimizacion. No estoy seguro si lo entend铆 correctamente.

MY NOTES FOR TEMPLATE

Cabe recalcar que el tema de css es algo de especificada y que saben que las l铆neas de css que son importante son las que se escriben al final, siempre van a ser mas importantes que las que est谩n arriba es como si se sobrescribieran.

class myElement extends HTMLElement{
  
  constructor(){
    super();



    
  }

  //Generamos una funcion en cual tendremos nuestro template html y esta
    //Funcion retornara este template
  getTemplate(){

    const template = document.createElement('template');
    template.innerHTML = `
      <section>

        <h2>Hola mundo!</h2>
        <div>

          <p> Soy text ejemplo<p>
        
        </div>
      
      </section>

  <!-- Para utilizar nuestros estilos de nuestro metodo lo llamamos desde nuestro template html
       para que se agreguen -->    
      ${this.getStyles()}

    `;
    return template
  }
  //Podremos generar otro metodo para poner los estilos, pero esto mas que todo se hace por simples
    //Buenas practicas pero se puede hacer de otras maneras.
  getStyles(){
    return`

      <style>
        h2{

          color:red;
        }
      </style>
    
    `
  }
  //Generamos otro metodo para que el contenido de nuestra etiqueta template se pueda clonar
    //Para poderlo agregar al dom
  render(){

    //Agregamos el elemento al dom por dentro utilzamos la funcion que genera el template
      //y utilizamos el content.clone(true) para clonar el elemento
        //Le ponemos true porque si este fuera false solo tomaria las etiquetas padre y no
          //Todo lo que tienen por dentro las etiquetas

    this.appendChild(this.getTemplate().content.cloneNode(true))

  }

  
  connectedCallback(){
    //Inicializamos en el dom el metodo de render
    this.render();
    


  }

}

customElements.define('my-element', myElement);

La forma de usar los templates es, crear un c贸digo base entre las etiquetas <template>, es decir una plantilla.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Template</title>
  </head>
  <body>
    <h2 class="title">Soy un Template</h2>
    <template>
      <div>
      <p>Texto de muestra</p>
      </div>
    </template>
    <script type="module" src="./template.js"></script>
  </body>
</html>

Luego en JavaScript procedes a clonar el c贸digo que esta entre las etiquetas <template>, le adicionar lo que requieres y lo renderizas, ejemplo:

const template = document.querySelector('template').content.querySelector('p');
for (let i = 1; i < 10; i++) {
  let clone = template.cloneNode(true);
  clone.textContent = `Ciclo: ${i}`;
  document.body.appendChild(clone);
}

En el explorador se ve as铆:

Soy un Template
Ciclo: 1
Ciclo: 2
Ciclo: 3
Ciclo: 4
Ciclo: 5
Ciclo: 6
Ciclo: 7
Ciclo: 8
Ciclo: 9

HTML Template

El聽elementoHTML聽<template>聽es un mecanismo para mantener el聽contenido聽HTML聽del lado del cliente que no se renderiza cuando se聽carga una聽p谩gina, pero que posteriormente puede ser instanciado durante el tiempo de ejecuci贸n empleando JavaScript.

Piensa聽en聽la plantilla como un fragmento de contenido que est谩 siendo almacenado para un uso posterior en el documento. El analizador procesa el contenido del elemento聽<template>聽durante la carga de la p谩gina, pero s贸lo lo hace para asegurar聽que esos聽contenidos son v谩lidos; sin embargo, estos contenidos del elemento no se renderizan.

Para lo que nos sirve la etiqueta <template> es justamente para tener una plantilla, que posteriormente utilizaremos para agregarle contenido din谩mico con JavaScript para a帽adirlas al DOM, la plantilla como tal nunca se mostrar谩 en la p谩gina, s贸lo se mostrar谩n los nodos creados desde JavaScript que la utilizaron como base para ser creados.

<!-- Creamos la plantilla -->
<template id="template-card">
	<figure>
		<img />
		<figcaption></figcaption>
	</figure>
</template>
const $container = document.querySelector(".container"),
  $template = document.getElementById("template-card").content,
  $fragment = document.createDocumentFragment(),
	cardsContent = [
    {
      title: "Tecnolog铆a",
      img: "https://placeimg.com/200/200/tech",
    },
    {
      title: "Animales",
      img: "https://placeimg.com/200/200/animals",
    }
  ];
// Por cada imagen que obtenemos de una API (por ejemplo) utilizaremos la plantilla y s贸lo le agregaremos el contenido
cardsContent.forEach((el) => {
  $template.querySelector("img").setAttribute("src", el.img);
  $template.querySelector("img").setAttribute("alt", el.title);
  $template.querySelector("figcaption").textContent = el.title;
  let $clone = document.importNode($template, true);
  $fragment.appendChild($clone);
});

$container.appendChild($fragment);

No se le entiende porque mezcla todo

Recomendaci贸n

No se si alguien mas a tenido este problema de que se le duplica el codigo o simplemente no se renderiza en lo particular es muy importante al trabajar con los web components
aperturar y cerrar de forma correcta cada etiqueta
<etiqueta></etiqueta> ya que podemos tener algunos inconvenientes al momento de renderizar

Un tip que lei no me acuerdo donde y me gusto es de cambiar el modo del lenguaje a HTML para escribir el template.innerHTML y que las etiquetas las cree de forma automatica

Para que se usa el template 驴?

Bueno al crear el nodo Template con Js nos sirve para simplemnte tener una base desde donde trabajar, en el ejemplo de la clase Diego genero la semantica dentro de un Section para tener un mejor control semantico y visual. La etiqueta simplente proporciono precisamente esa base para ahi colocar el codigo

Fue curioso, intente crear mi template y su contenido con createElement y append pero parece que al hacerlo de esa manera no funciona bien la clonaci贸n (segui el proceso y funciono hasta donde se veia en consola pero faltaba clonarlo, al clonarlo ya no funcionaba), usando el template literal si funciono con normalidad y luego me pregunte si tenia que ver con que no inicializamos los nodos en el constructor pero seguia sin funcionar.

Ahora me pregunto si el nombre del 鈥渢emplate literal鈥 tendr谩 que ver con esta etiqueta template y me quede con la duda de porque solo funciona usando innerHTML y no de la otra manera.

Se podr铆a decir entonces que para el caso de una p谩gina en donde mi header se repite en todas las pantallas del proyecto puedo crear el _template _ y solo resta llamarlo en cada uno de los archivos del HTML?

Tip:

Para escribir HTML con atajos o ayudas, ve a la parte de abajo que dice Javascript, cambia a html y de nada.

Ya cuando no uses HTML cambia a HTML.

Ojo que el audio falla gachamente.

class Element extends HTMLElement {
    constructor(){
        super();
    }
    getTemplate() {
        const template = document.createElement('template');
        template.innerHTML = ` 
            <section>
                <h2>Hello Guys</h2>
                <div>
                    <p>Texto de ejemplo</p>
                </div>
            </section>
        `;
        return template;
    }

    render() {
        this.appendChild(this.getTemplate().content.cloneNode(true));
    }

    connectedCallback() {
        this.render();
    }
}

customElements.define("my-element", Element);```

,