Una sinfonía en C#

Un pequeño aporte a la comunidad de habla hispana.

Comenzando con NodeJS en Windows

La idea de este post es introducir un poco en NodeJS y hacer nuestra primera experiencia utilizando Windows solamente.

Qué es NodeJS?

Lo voy a explicar en forma muy resumida: El navegador Google Chrome está formado por varios componentes, WebKit por ejemplo, pero tal vez el más sobresaliente sea V8 un motor de Javascript. Lo interesante de V8 es que es Open Source y que al ser un componente es posible ejecutarlo sin el contexto del navegador, bien, basado en esta idea un Ryan Dahl creo Node sumando un set de librería de base para permitir hacer cosas que Javascript y V8 no pueden, como acceder el sistema de archivos, o recibir TCP por ejemplo.

NodeJS es no-bloqueante

Una característica central en NodeJS es que es no-bloqueante, es decir que no existe la posibilidad de bloquear la ejecución, vamos a ver que cuando utilicemos una función en la gran mayoría de los casos vamos a tener que pasar otra función como parámetro para que NodeJS la invoque cuando termine con la tarea, a esto se le llama “callback”, por ejemplo:

fs.readFile('archivo.txt', function (err, data) {
  if (err) throw err;
  console.log(data);
});

notemos que el segundo parámetro de la función readFile es un función anónima (podría ser el nombre de una función) que es llamada cuando se termina con la lectura del archivo, este proceso no detiene la ejecución.

Librería base

Otra característica interesante de NodeJS es una muy buena librería base que permite hacer casi todo lo que necesitamos, pongo un pequeño listado, en la documentación están con más detalle:

  • Timers
  • Utilities
  • Events
  • Buffer
  • Stream
  • Crypto
  • TLS/SSL
  • String Decoder
  • File System
  • Path
  • Net
  • UDP/Datagram
  • DNS
  • HTTP
  • HTTPS
  • URL
  • Query Strings
  • Assertion Testing
  • Debugger

y algunas más.

Instalación en Windows

Actualmente la versión para Windows no tiene nada que envidiar a la versión para Linux y de hecho existe una versión para 32bits y otra para 64bit que son los clásicos instaladores msi que se encargan de copiar y registrar todo al estilo Windows.

Una vez instalado NodeJS podemos ir a la consola y probar algunas cositas para empezar

Lo primero que podemos hacer para sentir un poco el gusto de Node.js es invocarlos desde la línea de comandos y probar un poco de javascript desde ahí mismo.

image

 

como vemos podemos ejecutar código Javascript y NodeJS lo va ejecutando, pero si bien esto es interesante no se puede hacer mucho, el gran sabor lo encontramos cuando interactuamos con la librería de base de NodeJS

Primer ejemplo, leer un archivo.

Utilizando las librerías de base de NodeJS podemos hacer cosas que Javascript no puede cuando corre dentro del navegador, por ejemplo leer un archivo, el ejemplo es bien sencillo, vamos a leer el contenido de un archivo y mostrarlo por consola:

Cómo ejecutar un archivos js con NodeJS?

Una forma más adecuada de trabajar con NodeJS es escribir nuestro código en un archivo y indicar a Node que lo ejecute, esto es bien simple, sólo hay que hacer:

node nombreArchivo

La extensión del archivo no tienen gran importancia pero es una buena idea que sea .js.

Entonces el código que vamos a escribir para leer el contenido de un archivo y mostrarlo por consola es el siguiente:

var fs = require("fs");
fs.readFile("a.txt", "utf-8",function(err, data){
	console.log(data);
});

tengo un archivo llamado “a.txt” en el mismo directorio que el código de este script, lo ejecutamos

image

vamos a analizar línea a línea el código

var fs = require("fs");

esta línea es muy importante, lo que hacemos es importar una funcionalidad que nos permite manipular el sistema de archivos, la forma general de hacerlo es utilizando la función require y esta nos devuelve un objeto con el que interactuamos, en este caso la variable fs nos permite acceder a la funcionalidad.

fs.readFile("a.txt", "utf-8",function(err, data){
	console.log(data);
});

en estas líneas utilizamos la función readFile, como dijimos al principio nos pide una función como parámetro para invocarla cuando termine la lectura.

Otro detalle interesante es la existencia de un objeto console (similar al existente en los navegadores utilizado para debugging) que nos permite escribir en consola.

Bien, por el momento vamos a dejarlo acá, seguiremos con NodeJS conociendo algunos trucos.

Nos leemos.

Nuevo taller sobre jQuery en Buenos Aires

Es grato anunciar que nuevamente voy a dictar un taller sobre jQuery en Buenos Aires, una vez en las instalaciones del Grupo de usuarios de Microsoft (creo que debe ser el séptimo u octavo sobre el tema) en este caso la mecánica va a ser levemente diferente, cada uno deberá llevar su PC.

Práctica y más práctica

Un punto destacable es que la dinámica será del tipo “repetir y desafiar” es decir, yo voy a explicar algún concepto, luego mostrar un ejemplo y después proponer que hagan algo similar pero yendo un paso más allá (en general con una trampa Lengua fuera ) la idea es que el que no hace no aprender como decía un profesor mío.

Vamos a cubrir desde temas básicos hasta trucos de integración con Visual Studio y llamadas asincrónica.

La cita

Serán cuatro encuentros de tres horas, las fechas son un poco raras porque hay un feriado en medio, así que va a ser un lunes, martes, martes y lunes.

lunes 13 de agosto de 2012, continúa martes 14, martes 21 finaliza el lunes 27 de agosto de 18:30 a 21:30 hs.

Para registrarse deben entrar acá, los espero.

Templates con WinJS

Cuando queremos representar datos en nuestras páginas a partir de un template que se repite, lo más recomendable es utilizar un motor de templates como JsRender o JsViews, la pregunta es qué alternativas tenemos en WinJS?

Motor de templates integrado en WinJS

Ya existe un tipo definido para manejar templates dentro de WinJS

new WinJS.Binding.Template();

con él podemos indicar a un ListView cómo renderizar cada ítem, y también podemos generar nuestros templates y utilizarlos sobre un elemento del DOM.

Primer crear el template en HTML

Vamos a crear un proyecto metro en blanco y modificar el HTML por defecto para que se vea así:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Application16</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.0.6/css/ui-dark.css" rel="stylesheet">
    <script src="//Microsoft.WinJS.0.6/js/base.js"></script>
    <script src="//Microsoft.WinJS.0.6/js/ui.js"></script>

    <!-- Application16 references -->
    <link href="/css/default.css" rel="stylesheet">
    <script src="/js/default.js"></script>
</head>
<body>
<p>
    <div id="template">
        <span data-win-bind="innerText:valor"></span>
    </div>
</p>
    <div id="container"></div>
</body>
</html

La idea es sencilla, utilizar el div con id template como template y renderizarlo dentro del div con id container

Antes que eso vamos a correr la aplicación y ver qué pasa

image

Nada, vemos la pantalla en negro, cosa que en principio está bien, pero vamos a ver el DOM Explorer a ver qué es lo que realmente tiene el navegador en memoria

image

image

Vemos que el div template se está renderizando cosa que no es deseable, sin embargo no nos preocupamos, vamos a default.js y hacemos una pequeña modificación para decirle a WinJS que ese elemento debe ser tratado como un template.

(function () {
    "use strict";

    var app = WinJS.Application;

    app.onactivated = function (eventObject) {
                        WinJS.UI.processAll().then(function () {

                            //recuperamos el elemento del DOM
                            var templateElement = document.querySelector("#template");
                            //creamos un template a partir del elemento recuperado
                            var template = new WinJS.Binding.Template(templateElement);

                        });
    };

    app.start();
})();

Simplemente recuperamos el elemento del DOM y creamos un objeto del tipo WinJS.Binding.Template a partir de él, corremos la aplicación y vemos el DOM Explorer nuevamente

image

Vemos que WinJS agregó al elemento que definimos como template “display: none” para que no se vea en la página, entonces primer tema solucionado.

Renderizando datos a partir del tempalte

Ahora vamos a crear un set de datos y utilizar el template recién definido

(function () {
    "use strict";
    //creamos un objeto con una propiedad
    var data = {valor:"primer valor del set de datos"};

    var app = WinJS.Application;

    app.onactivated = function (eventObject) {
                        WinJS.UI.processAll().then(function () {

                            //recuperamos el elemento del DOM
                            var templateElement = document.querySelector("#template");
                            //creamos un template a partir del elemento recuperado
                            var template = new WinJS.Binding.Template(templateElement);
                            //recuperamos el elemento sobre el cual vamos a renderizar los datos
                            var target = document.querySelector("#container");
                            //renderizamos los datos sobre el destino
                            template.render(data, target);
                        });
    };

    app.start();
})();

creamos una variable en la que colocamos un objeto que será nuestro origen de datos, luego utlizamos la función render del template para utlizar esos datos y renderizar el resultado sobre el destino.

image

Perfecto, qué pasa si queremos renderizar un array de datos, entonces tenermos que usar un bucle del siguiente modo:

(function () {
    "use strict";
    //creamos un objeto con una propiedad
    var data = [{ valor: "primer valor del set de datos" }, { valor: "segundo valor del set de datos" }, { valor: "tercer valor del set de datos" }];

    var app = WinJS.Application;

    app.onactivated = function (eventObject) {
                        WinJS.UI.processAll().then(function () {

                            //recuperamos el elemento del DOM
                            var templateElement = document.querySelector("#template");
                            //creamos un template a partir del elemento recuperado
                            var template = new WinJS.Binding.Template(templateElement);
                            //recuperamos el elemento sobre el cual vamos a renderizar los datos
                            var target = document.querySelector("#container");

                            //renderizamos los datos sobre el destino
                            for (var i = 0; i < data.length; i++) {
                                template.render(data[i], target);
                            }                                                       
                        });
    };

    app.start();
})();

y con eso solucionamos el problema, o podemos utilizar la función foreach que agrega WinJS a los array, del siguiente modo:

(function () {
    "use strict";
    //creamos un objeto con una propiedad
    var data = [{ valor: "primer valor del set de datos" }, { valor: "segundo valor del set de datos" }, { valor: "tercer valor del set de datos" }];

    var app = WinJS.Application;

    app.onactivated = function (eventObject) {
                        WinJS.UI.processAll().then(function () {

                            //recuperamos el elemento del DOM
                            var templateElement = document.querySelector("#template");
                            //creamos un template a partir del elemento recuperado
                            var template = new WinJS.Binding.Template(templateElement);
                            //recuperamos el elemento sobre el cual vamos a renderizar los datos
                            var target = document.querySelector("#container");

                            //renderizamos los datos sobre el destino
                            data.forEach(function (item) {
                                template.render(item, target);
                            });
                        });
    };

    app.start();
})();

y listo:

image

Utilizando templates remotos

Una opción interesante es la capacidad de poder utilizar un template procedente de otro archivo, esto es bien sencillo, creamos un nuevo archivo template.html y colocamos todo el contenido de nuestro template dentro.

<div id="template">
    <p>
        <span data-win-bind="innerText:valor" ></span>
    </p>
</div>

y modificamos el código javascript para utilizar el template externo

(function () {
    "use strict";
    //creamos un objeto con una propiedad
    var data = [{ valor: "primer valor del set de datos" }, { valor: "segundo valor del set de datos" }];

    var app = WinJS.Application;

    app.onactivated = function (eventObject) {
                        WinJS.UI.processAll().then(function () {

                            //recuperamos el elemento del DOM
                            var templateElement = document.querySelector("#template");
                            //creamos un template a partir del archio remoto
                            var template = new WinJS.Binding.Template(null, { href: "/html/template.html" });

                            //recuperamos el elemento sobre el cual vamos a renderizar los datos
                            var target = document.querySelector("#container");

                            //renderizamos los datos sobre el destino
                            data.forEach(function (item) {
                                template.render(item, target);
                            });
                        });
    };

    app.start();
})();

simplemente cuando creamos el objeto template le indicamos el parámetro href apuntando al archivo externo, el resto es igual.

Hasta la próxima.

Cómo tener intellisense de WinJS en módulos Javascript?

Una buena costumbre al desarrollar aplicaciones metro con Javascript es tener nuestro código en módulos separados utilizando funciones autoejecutables y así tener un scope acotado.

Existe un pequeño problema, al ser un archivo separado no tenemos intellisense de las librerías de WinJS (ni de ningúna otra), algo así:

image

Este problema se incrementa ya que no tenemos referencias físicas en el proyecto de los archivos base de WinJS, sino que accedemos a ellos a través de un path especial

image

Sin embargo podemos hacer algo para tener intellisense del WinJS en nuestro módulo del siguiente modo:

image

Simplemente agregamos los tags reference con el atributo path apuntando a los path especiales de las librerías de WinJS y tenemos intellisense.

Hasta la próxima.

Charla a través de Internet sobre Aplicaciones Metro con Javascript

UPDATE 2012.04.12
Se aplazó la VAN para el Viernes 27 de Abril a las 18:00hs GMT

Windows 8 logo

Una vez más voy a tener la suerte de participar de una VAN (Virtual Alt.Net), para la comunidad de Alt.Net Hispano, en esta oportunidad será sobre Aplicaciones Metro con Javascript.

VW Camper

El tema

La idea hablar de Windows 8 y las aplicaciones metro, comenzando con un poco de teoría sobre la plataforma y qué son y cuáles los lineamientos de las aplicaciones Metro.

Vamos a tratar de ir contando un poco el modelo de programación y cómo nos ayuda WinJS para todo esto

No voy a estar sólo

En la VAN me va a acompañar Rubén Altman del equipo de Kinetica y tal vez algunas sorpresas.

La fecha

Será el viernes 13 de Abril a las 18hs GMT, las 15hs de Argentina.

Cómo asistir?

Para participar de la VAN es necesario tener instalado Microsoft Office Live Meeting 2007 client

El Link de acceso es acá

Pueden dejar comentarios e inquietudes en la lista de correo

Para más información acerca de las VAN pueden acceder acá

Entonces, hecha la invitación nos vemos el 13.

Leonardo.