KnockoutJS - Plantillas

Templatees un conjunto de elementos DOM que se pueden utilizar repetidamente. La creación de plantillas facilita la creación de aplicaciones complejas debido a su propiedad de minimizar la duplicación de elementos DOM.

Hay 2 formas de crear plantillas.

  • Native templating- Este método admite enlaces de flujo de control como foreach, with y if. Estos enlaces capturan el marcado HTML existente en el elemento y lo utilizan como plantilla para elementos aleatorios. No se requiere una biblioteca externa para esta plantilla.

  • String-based templating- KO se conecta al motor de terceros para pasarle los valores de ViewModel e inyecta el marcado resultante en el documento. Por ejemplo, JQuery.tmpl y Underscore Engine.

Syntax

template: <parameter-value>

<script type = "text/html" id = "template-name">
   ...
   ...   // DOM elemets to be processed
   ...
</script>

Tenga en cuenta que type se proporciona como text/html en el bloque de script para notificar a KO que no es un bloque ejecutable, sino simplemente un bloque de plantilla que necesita ser renderizado.

Parameters

La combinación de las siguientes propiedades se puede enviar como valor de parámetro a la plantilla.

  • name - Esto representa el nombre de la plantilla.

  • nodes- Esto representa una matriz de nodos DOM que se utilizarán como plantilla. Este parámetro se ignora si se pasa el parámetro de nombre.

  • data - Esto no es más que datos que se mostrarán a través de la plantilla.

  • if - La plantilla se publicará si la condición dada da como resultado un valor verdadero o similar.

  • foreach - Servir plantilla en formato foreach.

  • as - Esto es solo para crear un alias en cada elemento.

  • afterAdd, afterRender, beforeRemove - Todos estos son para representar funciones invocables que se ejecutarán dependiendo de la operación realizada.

Observaciones

Representación de una plantilla con nombre

Las plantillas se definen implícitamente mediante el marcado HTML dentro de DOM cuando se utilizan con enlaces de flujo de control. Sin embargo, si lo desea, puede factorizar las plantillas en un elemento separado y luego hacer referencia a ellas por su nombre.

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Named Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { name: 'friend-template', data: friend1 }"></div>
      <div data-bind = "template: { name: 'friend-template', data: friend2 }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friend1 = { 
               name: 'Smith', 
               contactNumber: 4556750345, 
               email: '[email protected]' 
            };
            
            this.friend2 = { 
               name: 'Jack', 
               contactNumber: 6789358001, 
               email: '[email protected]' 
            };
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Realicemos los siguientes pasos para ver cómo funciona el código anterior:

  • Guarde el código anterior en template-named.htm archivo.

  • Abra este archivo HTML en un navegador.

  • Aquí, la plantilla de amigo se usa 2 veces.

Usando "foreach" en la plantilla

A continuación se muestra un ejemplo de uso foreach junto con el nombre de la plantilla.

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - foreach used with Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { name: 'friend-template', foreach: friends }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friends = [
               { name: 'Smith', contactNumber: 4556750345, email: '[email protected]' },
               { name: 'Jack', contactNumber: 6789358001, email: '[email protected]' },
               { name: 'Lisa', contactNumber: 4567893131, email: '[email protected]' }
            ]
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Realicemos los siguientes pasos para ver cómo funciona el código anterior:

  • Guarde el código anterior en template-foreach.htm archivo.

  • Abra este archivo HTML en un navegador.

  • Aquí, el control foreach se usa en el enlace de plantillas.

Creación de alias utilizando como palabra clave para cada elemento

A continuación se muestra cómo se puede crear un alias para un elemento foreach:

<div data-bind = "template: { 
   name: 'friend-template', 
   foreach: friends, 
   as: 'frnz' 
}"></div>

Resulta fácil hacer referencia a los objetos principales desde el interior de los bucles foreach creando un alias. Esta función es útil cuando el código es complejo y está anidado en varios niveles.

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - using alias in Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <ul data-bind = "template: { 
         name: 'friend-template', 
         foreach: friends, 
         as: 'frnz' 
      }"></ul>

      <script type = "text/html" id = "friend-template">
         <li>
            <h3 data-bind = "text: name"></h3>
            <span>Contact Numbers</span>
            <ul data-bind = "template: { 
               name : 'contacts-template', 
               foreach:contactNumber, 
               as: 'cont'
            } "></ul>
            <p>Email-id: <span data-bind = "text: email"></span></p>
         </li>
      </script>

      <script type = "text/html" id = "contacts-template">
         <li>
            <p><span data-bind = "text: cont"></span></p>
         </li>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friends = ko.observableArray ( [
               { 
                  name: 'Smith', 
                  contactNumber: [ 4556750345, 4356787934 ], 
                  email: '[email protected]' 
               },
               
               { 
                  name: 'Jack', 
                  contactNumber: [ 6789358001, 3456895445 ], 
                  email: '[email protected]' 
               },
               
               { 
                  name: 'Lisa', 
                  contactNumber: [ 4567893131, 9876456783, 1349873445 ],  
                  email: '[email protected]' 
               }
            ]);
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Realicemos los siguientes pasos para ver cómo funciona el código anterior:

  • Guarde el código anterior en template-as-alias.htm archivo.

  • Abra este archivo HTML en un navegador.

  • Se utiliza alias en lugar del nombre completo de las matrices.

Uso de afterAdd, beforeRemove y afterRender

Hay situaciones en las que es necesario ejecutar una lógica personalizada adicional en los elementos DOM creados por la plantilla. En tal caso, se pueden utilizar las siguientes devoluciones de llamada. Considere que está usando foreach elemento entonces -

afterAdd - Esta función se invoca cuando se agrega un nuevo elemento a la matriz mencionada en foreach.

beforeRemove - Esta función se invoca justo antes de eliminar el elemento de una matriz mencionada en foreach.

afterRender - La función mencionada aquí se invoca cada vez que se procesa foreach y se agregan nuevas entradas a la matriz.

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Use of afterRender Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
      <script src = "https://code.jquery.com/jquery-2.1.3.min.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { 
         name: 'friend-template', 
         foreach: friends , 
         afterRender: afterProcess
      }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
         <button data-bind = "click: $root.removeContact">remove </button>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            self = this;
            this.friends = ko.observableArray ([
               { name: 'Smith', contactNumber: 4556750345, email: '[email protected]' },
               { name: 'Jack', contactNumber: 6789358001, email: '[email protected]' },
            ])

            this.afterProcess = function(elements, data){
               $(elements).css({color: 'magenta' });
            }

            self.removeContact = function() {
               self.friends.remove(this);
            }
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
   </body>
</html>

Output

Realicemos los siguientes pasos para ver cómo funciona el código anterior:

  • Guarde el código anterior en template-afterrender.htm archivo.

  • Abra este archivo HTML en un navegador.

  • Aquí, la función afterProcess se ejecuta cada vez que se procesa foreach.

Elegir una plantilla de forma dinámica

Si hay varias plantillas disponibles, entonces se puede elegir una dinámicamente haciendo el nombre como observableparámetro. Por lo tanto, el valor de la plantilla se volverá a evaluar cuando cambie el parámetro de nombre y, a su vez, los datos se volverán a representar.

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Dynamic Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { 
         name: whichTemplate, 
         foreach: friends 
      }"></div>

      <script type = "text/html" id = "only-phon">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
      </script>

      <script type = "text/html" id = "only-email">
         <h3 data-bind = "text: name"></h3>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
   
            this.friends = ko.observableArray ([
               {
                  name: 'Smith', 
                  contactNumber: 4556750345, 
                  email: '[email protected]', 
                  active: ko.observable(true)
               },
               
               {
                  name: 'Jack', 
                  contactNumber: 6789358001, 
                  email: '[email protected]', 
                  active: ko.observable(false)
               },
            ]);

            this.whichTemplate = function(friends) {
               return friends.active() ? "only-phon" : "only-email";
            }
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Realicemos los siguientes pasos para ver cómo funciona el código anterior:

  • Guarde el código anterior en template-dynamic.htm archivo.

  • Abra este archivo HTML en un navegador.

  • La plantilla a utilizar se decide en función del valor de la bandera activa.

Usando motores externos basados ​​en cadenas

Las plantillas nativas funcionan perfectamente con varios elementos de flujo de control incluso con bloques de código anidados. KO también ofrece una forma de integrarse con una biblioteca de plantillas externa como el motor de plantillas Underscore o JQuery.tmpl.

Como se menciona en el sitio oficial, JQuery.tmpl ya no se encuentra en desarrollo activo desde diciembre de 2011. Por lo tanto, las plantillas nativas de KO solo se recomiendan en lugar de JQuery.tmpl o cualquier otro motor de plantillas basado en cadenas.

Consulte el sitio oficial para obtener más detalles al respecto.