KnockOutJs II: Continuamos

ForTutorial

Continuación de KnockOutJS I: Empezando, aquí explicaremos con mas profundidad como utilizar KnockOut, propiedades, recorrer listados, …

Que veremos

Como he dicho en el resumen, propiedades que puede modificar KnockOut, condicionales (si esta propiedad tiene este valor, muéstrame esto), recorrer listados, como rellenar una combo y como modificar los listados.

Continuamos

Como vimos en el anterior artículo, KnockOutjs (en adelante ko) utiliza el tag de html data-bind para poder enlazar los datos. En el data-bind el formato es de clave-valor, pudiendo modificar cualquier propiedad.

Podemos indicar el texto que se muestra, o el valor que tendrá un elemento, esto lo vimos en el primer artículo ( las propiedades text y value), pero también podemos modificar la propiedad Style:

 style: { color: 'red', fontWeight: 'bold' }

Podemos poner que un elemento se asocie a una clase:

 css: claseCss

Introducir texto en formato html en el elemento:

 html: < p>Hola< /p>

El introducir texto html nos puede ir bien para introducir paneles o «div» en función de si hay datos (por ejemplo). Estos solo han sido algunos ejemplos de atributos, podemos modificar cualquier propiedad que tenga el elemento.

Aparte, el valor que introducimos puede ser condicional, en función de si tiene valor pones el texto de un color o de otro, …
Este formato es el siguiente:

 
 data-bind="text: style: { color: descripcion() == '' ? 'No hay descripcion' : descripcion() }"

Esto por ejemplo, mira si la descripción tiene texto. El formato de la condición es igual que el iif de C# condición ? true : false.

Ahora vamos a ver como recorrer un listado. Continuaremos con el ejemplo de cervezas. Modificaremos el js donde está el ViewModel de ko, crearemos un objeto oBeer y le pasaremos por parámetros el nombre y la descripción. Después pondremos la función que será el ViewModel, donde, de momento, tendremos una propiedad que contendrá una lista de oBeers y tiene que quedar así:

function oBeer(n, d){
   var self = this;
   self.Nombre = ko.observable(n); 
   self.Descripcion = ko.observable(d);  
}

 function beerViewModel() { 
   var  self = this;
    self.Beers = ko.observableArray([
                    new oBeer('Belcebuth', 'Cerveza francesa tostada'),
                    new oBeer('Franciskaner', 'Cerveza de trigo')
                 ]);

 }  
ko.applyBindings(new beerViewModel());

**La variable self es recomendable en js en general, cuando hacemos objetos, porque algunas veces puede ser que confunda el this de tu función/objeto con el this de la página.

Aquí podemos ver una nueva funcionalidad de ko, ko.observableArray(), que como deduciréis por su nombre, añade un observable a una propiedad tipo array.
Aparte tendremos que modificar el HTML que teníamos, para que quede así:

 < h3> Lista de Cervezas < /h3>
< div data-bind="foreach:Beers "> 
    Nombre: < label data-bind="text: Nombre"> < br/> 
    Descripcion: < label data-bind="text: Descripcion"> 
< /div>

(Acordaos que pongo un espacio en el código html por que si no, no me mostraría el código).

Aquí podemos ver una propiedad de ko que es foreach, que recorre una colección de objetos.

Si ejecutamos tendríamos que ver los 2 objetos de beers.

Ahora Añadiremos la posibilidad de añadir, primero lo pondremos con texto predefinido, añadimos una propiedad en el ViewModel que sea una función para añadir a el array una cerveza:

      //Acontinuación de self.Beers
	 self.add = function (){      
                       self.Beers.push(new oBeer("Estela Artois", "cerveza rubia"))
                    };

y en el HTML un botón para añadirla, tendremos que indicar que el click es la función:

  
< input type="button" data-bind=" click:add" value="Añadir!!">< /input>

Ahora nos dejará añadir objetos a el array. Ahora pondremos que tengamos que añadirlo, pero con 2 textbox.

Añadimos 2 propiedades al ViewModel:

	self.Nombre = ko.observable('');
    self.Descripcion = ko.observable('');

Y modificamos la función de add para que mire estas propiedades:

      self.add = function (){ 
                   self.Beers.push(
                       new oBeer(self.Nombre(), self.Descripcion()))
                    };

Después en el HTML, justo antes del botón añadimos los 2 textbox correspondientes:

Nombre: < input  data-bind="value: Nombre">< /input>
< br/>
Descripcion: < input  data-bind="value: Descripcion">< /input>

Y si probamos ahora la añadirá en función del texto.

Aparte de el foreach tenemos la clausula if e ifnot que es para que no te muestre el contenido de un div ( por ejemplo ) en función de la condición.

Vamos a ver como funcionan las combos.

En html, el formato sería así:

  
< select data-bind="options: lista, value: valor, optionsText: 'texto'">< /select>

El optionsText va entre comillas. En nuestro ejemplo sería algo parecido a esto:

 
< select data-bind="options: Beers, value: Nombre, optionsText: 'Descripcion'">< /select>

Así nos mostraría una combo con las descripciones. Ahora vamos a modificar nuestro ejemplo para que en lugar de label, muestre un textbox y un combo, y estos modifiquen el contenido:

Lo que tenemos que hacer es modificar el js para que quede así:

  function oBeer(n, d){
   var self = this;
   self.Nombre = ko.observable(n); 
   self.Descripcion = ko.observable(d);  
}

 function beerViewModel() { 
   var  self = this;
     self.NombreN = ko.observable('');
     self.DescripcionN = ko.observable('');
     self.Beers = ko.observableArray([
                    new oBeer('Belcebuth', 'Cerveza francesa tostada'),
                    new oBeer('Franciskaner', 'Cerveza de trigo')
                 ]);
     self.Desc= ko.observableArray([
                    'Cerveza francesa tostada',
                    'Cerveza de trigo'
                 ]);

     self.add = function (){ 
                   self.Beers.push(new oBeer(self.NombreN(), self.DescripcionN()))
                };                 
 }  
ko.applyBindings(new beerViewModel());

Lo único que ha cambiado es que hemos añadido un array con los tipos de cerveza, y en el HTML nos queda así:

     < h3> Lista de Cervezas < /h3>

< div data-bind="foreach:Beers ">
    Nombre: < input type="text" data-bind="value: Nombre" /> 
    < br/>
       Descripcion: < select data-bind="                     options: $root.Desc,                     value: Descripcion                     ">< /select>
    < br/>
< /div>

< br/>

Nombre: < input  data-bind="value: NombreN">< /input>
< br/>
Descripcion: < input  data-bind="value: DescripcionN">< /input>

< input type="button" data-bind=" click:add" value="Añadir!!!">< /input>

Fijaros que como estamos dentro del foreach tenemos que usar el $root para acceder a las propiedades del padre.

Para continuar explicando ko, lo que haré es aprovechar y hacer un manual de MVC .NET y una vez acabado, aplicar en ejemplo mas real.