Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
miércoles, 28 de noviembre de 2007
De vez en cuando reviso las palabras por las que se llega a Variable Not Found a través de los buscadores, más que nada porque suelen reflejar dudas o problemas comunes de los desarrolladores y pueden servir como inspiración sobre nuevos temas a tratar en el blog.

Pues bien, llevo tiempo observando que hay muchas personas que preguntan a Google algo similar a "anular postback en botón", es decir, se tienen dudas sobre cómo evitar el disparo del postback al pulsar un botón de un formulario ASP.Net. El tema me ha parecido tan interesante que intentaré dar una respuesta a la duda estudiando algunas de las distintas posibilidades que pueden darse. Eso sí, si echáis en falta algún caso, no dudéis en comentarlo y lo trataremos lo antes posible.


I. ¿Hablamos de botones con lógica exclusivamente en cliente?

La primera cuestión es preguntarse para qué queremos un botón que no realice un postback al ser pulsado. Pensad que si todas las acciones desencadenadas por la pulsación del botón se realizarán en cliente es posible que no necesitemos un control ASP.Net. Imaginemos, por ejemplo, un botón que queremos que haga un cálculo en el cliente y muestre un cuadro de alerta con el resultado... ¿es necesario que sea un control de servidor (runat="server")? Seguro que no.

Para este caso lo más apropiado es incluir en el .aspx un HTML INPUT de los de toda la vida:

<input id="Button1" type="button" value="button"
onclick="hacerAlgo();" />
 
Si eres de los que prefieren arrastrar y soltar, puedes hacer exactamente lo mismo utilizando los controles incluidos en la pestaña HTML de Visual Studio, en este caso el llamado Input(Button). El resultado visual será idéntico al de un Button (un botón de servidor) y estaremos aligerando tanto la página enviada al cliente como la carga del servidor.

II. Anular el postback en un botón de servidor

Otra posibilidad es que vayas a usar un control de servidor (un Button, por ejemplo) y sólo bajo determinadas circunstancias quieras anular el postback desde el cliente. Obviamente, estas circunstancias serían calculadas/obtenidas por script, por lo que podríamos aplicar un patrón como el siguiente:

...
<asp:Button ID="Button1" runat="server"
Text="Pulsa"
OnClientClick="return comprueba();" />
...
<script type="text/javascript">
function comprueba() {
return confirm("Confirme el postback");
}
</script>
 
Como se puede observar, se ha modificado la propiedad OnClientClick del botón para hacer que retorne el resultado de la llamada a la función comprueba(). Si ésta retorna cierto, se realizará el postback, mientras que si retorna falso, no lo hará. En el ejemplo anterior se permite al usuario decidir si desea enviar el formulario al servidor o no.

III. Anular la posibilidad de envíos múltiples

Hay otras ocasiones, sin embargo, en las que estamos utilizando un botón de servidor de forma normal y simplemente queremos evitar duplicidades en el envío del formulario, es decir, bloquear el botón correspondiente una vez el usuario lo haya pulsado la primera vez.

Esto es muy habitual debido a la falta de feedback: el usuario envía el formulario, se impacienta esperando la respuesta o no está seguro de haberlo enviado, y cual poseso, inicia un ataque implacable sobre el botón de envío. ¿A que os suena?

El comportamiento típico, adoptado por la mayoría de sitios web, es deshabilitar el botón y seguir con el postback. Sin embargo, esto que podría ser realmente sencillo mediante scripting, causa algún que otro problema cuando el botón es de tipo Submit, puesto que en determinados navegadores (por ejemplo IE6) no realizará el envío si lo está generando un botón deshabilitado. Una forma de evitar este problema es hacer que el botón no sea de tipo submit e incluir un pequeño script:

<asp:Button ID="Button2" runat="server"
Text="Pulsa"
OnClientClick="this.disabled=true"
UseSubmitBehavior="False"/>

Si el botón debe ser obligatoriamente de tipo submit, se deben utilizar soluciones alternativas. Googleando un poco he encontrado varias, como deshabilitar el botón pasadas unas décimas de segundo mediante un timer, o retocar los estilos del botón para, simplemente, hacerlo desaparecer y mostrar en su lugar un mensaje informativo. La mejor, para mi gusto, consiste en capturar el evento onsubmit del formulario web, así:

...
<form id="form1" runat="server" onsubmit="deshabilita()">
...
<script type="text/javascript">
function deshabilita()
{
var btn = "<%= Button1.ClientID %>";
if (confirm("Confirme postback"))
{
document.getElementById(btn).disabled = true;
return true;
}
return false;
}
</script>
 
Este último ejemplo lo he aprovechado para, además, mostrar cómo es posible realizar la captura del envío justo antes de que se produzca, en el evento OnSubmit, e introducir las confirmaciones de envío y deshabilitado de botones.

Publicado en Variable not found.
martes, 27 de noviembre de 2007
Aunque he visto que es conocido desde hace tiempo, yo me he enterado ahora de que en http://www.connectionstrings.com/ hay una excelente recopilación de cadenas de conexión a fuentes de datos de todo tipo:
  • Motores de bases de datos SQL Server, SQL Server 2005, SQL Server 2005 Compact Edition, Oracle, MySQL, Interbase, IBM DB2, Sybase, Informix, Ingres, Mimer SQL, Lightbase, Postgre SQL, Paradox, Firebird, AS/400 (iSeries), Pervasive, SQLBase, Progress y Caché.

  • Archivos de datos Excel 2007, Excel, texto plano, Access 2007, Access, Visual FoxPro / FoxPro 2.x DBF / FoxPro, SQLite y Filemaker.

  • Otras fuentes, como MS Project, Active Directory, Exchange, Lotus Notes, DSN y UDL.

Seguro que algún despistado (como el menda, todo sea dicho), todavía no lo conocía. Y es que no hay nada como internet para tener a mano toda la información que necesitamos.

Publicado en: Variable not found
lunes, 26 de noviembre de 2007
Hasta hoy no sabía que la arroba, además de permitir la definición de constantes string literales y multilíneas (mi gran descubrimiento del mes pasado), también puede ser utilizado en C# para utilizar nombres reservados del lenguaje como identificadores.

Según la especificación del lenguaje C#, un identificador (de una variable, clase, propiedad...) puede ser una de las palabras clave del lenguaje (for, if, int, string...) si va precedida por una arroba, permitiendo aberraciones como la siguiente:

class @class
{
public static void @static(bool @bool)
{
if (@bool)
System.Console.WriteLine("true");
else
System.Console.WriteLine("false");
}
}
 
En fin, dudo mucho que vaya a utilizar esta posibilidad alguna vez, pero está bien saber que existe.

Publicado en: Variable Not Found.
domingo, 25 de noviembre de 2007
Si existieran los diez mandamientos del programador, seguro que uno de ellos sería "comenta tu código". Y es que está claro que la mantenibilidad de una aplicación o módulo es posible siempre que los profesionales encargados de ella sean capaces de entender perfectamente qué hace el software y cómo lo hace, y es aquí donde un código correctamente documentado puede facilitar enormemente la tarea.

Todos los lenguajes de programación facilitan la inclusión de texto libre, no estructurado, con objeto de que el programador explique a futuros mantenedores del software los principales aspectos del código fuente que está observando, el por qué de determinadas decisiones, o, en definitiva, aclarar lo que considere oportuno. Sin embargo, esta libertad y falta de normalización acarrea una serie de inconvenientes que deben ser tenidos en cuenta, y que comentó Chad Myer hace unas semanas.

En primer lugar, es importante ser conscientes de que estos textos están fuertemente ligados al código que comentan y, obviamente, al no ser comprobados por ningún sistema automático (como un compilador), es fácil que contengan errores:

// Retorna la suma de a y b
public int multiplica(int a, int b)
{
...
 
Tampoco puede asegurarse que los comentarios sean útiles; de hecho, parte de los comentarios que leemos son obviables y totalmente innecesarios, auténticos insultos a la inteligencia, del tipo:

if (a > 5) // Si a es mayor que cinco, ...
counter = 0; // ... ponemos el contador a cero
...
 
La inclusión de este tipo de comentarios no harían sino añadir "ruido" a un código perfectamente inteligible de forma directa.

Y hablando de comentarios prescindibles, es curioso ver su utilización como vía de escape y desfogue de algunos programadores, que no dudan en añadir todo tipo de artillería a sus creaciones, como las mostradas en el Contador de palabrotas del Kernel de Linux, arremetiendo contra los usuarios, colegas o todo aquél que pase por delante en el momento apropiado.

Otro hecho bastante frecuente es que los comentarios sean introducidos al crear un código pero que no sean actualizados de forma paralela a éste, lo que da lugar a textos obsoletos y sin sentido en su contexto. Y no hablo sólo de actualizaciones tiempo después de su creación, también las realizadas minutos u horas después de la programación inicial como consecuencia de optimizaciones y refactorizaciones, incluso realizadas por el mismo desarrollador.

// Si x es true, retorna a+b
// Si no, retorna a-b
public int calcula(int a, int b)
{
...
 
A pesar de todos estos problemas, normalmente generados por falta de rigor durante su creación y actualización, los comentarios son absolutamente necesarios para el futuro mantenimiento de un sistema y deben tratarse como parte fundamental en una pieza de código y prestarle la misma atención que a éste. Recordemos la famosa frase de Martin Fowler:
"Cualquier tonto puede escribir código que entienden las computadoras. Los buenos programadores escriben código que entienden las personas"


Para ello, como dice Bernhard Spuida en su magnífico documento The Fine Art of Commenting, hay que luchar contra actitudes negativas como:
  • el orgullo del programador ("no me hacen falta comentarios para entender lo que hace cualquier código", "yo escribo código que entiende cualquiera"). No te engañes, un código medianamente complejo te llevará tiempo entenderlo en cuanto hayan pasado unos meses incluso a tí mismo, así que imagina a otro desarrollador.
  • la pereza y procrastinación ("ya comentaré el código más adelante"). No te engañes, no lo harás; además, se estima que el tiempo necesario para añadir comentarios útiles a un código se duplica (como mínimo) si no se realiza en el momento de la codificación.
  • la excusa del deadline ("el proyecto va demasiado apurado como para ponerme a comentar el código"). No te engañes, los minutos de tardarás en comentar apenas afectarán a los plazos, y sí añadirán mantenibilidad al sistema.

Y es que, citando a Ryan Campbell en su post Successful Strategies for Commenting Code,
"comentar el código es como limpiar el cuarto de baño; nadie quiere hacerlo, pero el resultado es siempre una experiencia más agradable para uno mismo y sus invitados"


Publicado en: Variable Not Found.
miércoles, 14 de noviembre de 2007
Pues no, esta entrada no trata de los diseños líquidos habituales en el mundo de la maquetación web, aunque podría parecer lo contrario. El término interfaz se utiliza en su acepción relativa a la orientación a objetos, y la fluidez se refiere a la continuidad en el movimiento de instancias entre distintas llamadas a métodos.

En pocas palabras, el uso de interfaces fluidos es un estilo cada vez más frecuente de programación, también llamado a veces "encadenamiento de métodos" (method chaining), que promueve la eliminación de código innecesario y engorroso para la realización de tareas frecuentes, sustituyéndolo por una secuencia natural, intuitiva y fluida de instrucciones que se encadenan de forma casi mágica.

Pero veámoslo con un ejemplo. Y ojo, que aunque lo codificaremos en C#, el concepto es perfectamente válido para otros lenguajes orientados a objetos, salvo por los aspectos sintácticos.

Imaginemos la clase Calculator, con un diseño como el mostrado a la izquierda, que es capaz de mantener un único valor (entero) y que soporta cinco operaciones: Get (para obtener el valor actual de la calculadora), Set (para establecerlo), y Add, Substract y Multiply (para sumarle, restarle y multiplicarle un valor respectivamente).

La forma habitual de operar con esta calculadora para obtener el resultado de un cálculo sería algo parecido a:
  Calculator calc = new Calculator();
calc.Set(0);
calc.Add(10);
calc.Multiply(2);
calc.Subtract(4);
Console.WriteLine("Resultado : " + calc.Get());
 
Como podemos observar, para realizar unas operaciones muy simples hemos necesitado demasiadas líneas de código, y además bastante repetitivas.

Veamos ahora cómo utilizando la técnica de interfaces fluidos podemos dejar este código en:
  Console.WriteLine("Resultado: " +
new Calculator().Set(0).Add(10).Multiply(2)
.Substract(4).Get()
);
 
El truco consiste en hacer que métodos que normalmente no devolverían ningún valor (métodos void, como los de la clase Calculator anterior) retornen referencias hacia el propio objeto, es decir, acaben con un return this;. De esta forma, la llamada a la función podrá ir seguida de otra llamada sobre el mismo objeto, que a su vez lo devolverá para el siguiente y así sucesivamente. Y de ahí el término "fluido": fijaos en el ejemplo anterior como la instancia de Calculator que es retornada por el constructor se utiliza directamente en la llamada Set(0), que a su vez la devuelve y es utilizada por Add(10)... ¿no es eso fluir, aunque el término suene algo poético?

Otro ejemplo, donde se utiliza la misma técnica, pero esta vez combinando instancias de distintas clases (fijaos que nada impide en la mayoría de lenguajes dividir las líneas de código como se muestra, facilitando así la lectura):

new Surface()
.Clear()
.Fill("white")
.CreateText()
.SetMessage("Hi, all!")
.SetColor("blue")
.Draw()
.CreateCircle(100, 100, 10)
.Fill("green")
.Draw()
.Border("red")
.Draw()
 
Este código muestra tres aspectos importantes. Primero, que es posible crear un pseudo-lenguaje de programación utilizando esta técnica, de hecho los fluent interfaces son muy utilizados en los DSL (Lenguajes Específicos de Dominio). En el ejemplo se puede intuir un lenguaje para el dibujo de figuras sobre una superficie.

Segundo, que la devolución de los métodos no tiene por qué limitarse a una única clase. En el código anterior, los métodos CreateText() y CreateCircle() retornan referencias a nuevas instancias de clases que representan estas figuras, que también hacen uso de interfaces fluidos. Los métodos Draw() de ambas retornan de nuevo una referencia a la instancia de la superficie (Surface) sobre la que están dibujando.

Tercero, se deja entrever la dificultad de desarrollar clases que permitan utilizar esta técnica, pues cada método debe devolver una referencia al objeto oportuno para facilitar el encadenamiento con el método posterior. Una elección incorrecta de la clase de devolución hará que la fluidez se rompa.

Finalmente, decir que los interfaces fluidos no son algo nuevo. Hay quien habla de su uso en SmallTalk antes de la década de los noventa (!), aunque el concepto se extendió a partir de la inclusión de una entrada en la Bliki de Martin Fowler comentándolo hace un par de años.

Hay también quien opina que los interfaces fluidos son algo más que el encadenamiento de métodos, que también existe en un código como name.Trim().ToUpper(), pues aporta una interfaz comprensible e intuitiva.

En cualquier caso, hace algún tiempo que esta técnica me llamó la atención y cada vez lo veo utilizado en más ocasiones, especialmente en contextos de frameworks y para implementar DSLs (como Quaere).
domingo, 11 de noviembre de 2007
Las primeras versiones de la plataforma .Net introdujeron el PostBack como el mecanismo de recarga de una página gracias al cual era posible la persistencia del estado de controles y la interacción con ellos de forma muy sencilla y potente en el lado del servidor, modificando la filosofía de programación de webs que habíamos usado hasta entonces (ASP clásico, CGIs...).

Sin embargo, si querías usar los controles de servidor en todo su esplendor te veías obligado a meter tareas completas dentro de una misma página; así, aquellas que presentaban funcionalidades relativamente complejas se convertían en batiburrillos donde se incluían formularios de entrada de datos, código de validaciones, formularios de salida de información, etc. Por ejemplo, podíamos tener en un mismo Webform paneles de introducción de criterios de búsqueda, paneles de información o errores, paneles con un grid para mostrar los resultados e incluso otro panel para mostrar una vista ampliada de un registro concreto, y jugar con las visibilidades para mostrar unos u otros en función de los pasos dados por el usuario.

Desde ASP.Net 2.0 es posible realizar los llamados "Cross Page PostBacks", o PostBacks hacia páginas distintas de la inicial, permitiéndonos separar funciones y hacer nuestro código un poco más legible, estructurado y reutilizable. El ejemplo anterior podría ser diseñado en tres páginas independientes, separando las distintas vistas, una solución mucho más limpia:
  • en la primera estaría el formulario de introducción de criterios.
  • en la segunda podríamos simplemente tomar los parámetros de la anterior y mostrar un listado con los resultados obtenidos, o bien un mensaje de información si no hay coincidencias.
  • en la tercera podríamos montar una ficha con los datos detallados de un elemento, que habría sido seleccionado por el usuario en la página anterior.
¿Y cómo se hace? Sencillo.

En primer lugar, hay que modificar el comportamiento de los botones de acción (o similar, de hecho también podría ser ImageButtons o LinkButtons) para que realicen el envío a otra página, indicándole su URL en la propiedad PostBackUrl. Eso hará que, tras su pulsación, el control sea enviado inmediatamente al archivo .aspx que se defina en la misma.

Un aspecto muy a tener en cuenta es el término "inmediatamente": el control es transferido a la nueva página sin ejecutar posibles validaciones en servidor, por lo que podrían llegar gazapos a la segunda. Sin embargo, si los validadores son en cliente, se ejecutarán con normalidad (si el usuario no tiene desactivado Javascript, of course!).

Ya en la página destino, hay varias opciones para recuperar el valor de los controles de la página invocadora. La primera de ellas, la más sencilla, consiste en usar la propiedad PreviousPage de la clase Page para obtener una referencia hacia la página de origen y obtener sus controles de la siguiente forma:

if (PreviousPage != null)
{
TextBox txt =
(TextBox)PreviousPage.FindControl("TextBox1");
Label1.Text = txt.Text; // Por ejemplo
}

Sin embargo, no es una solución aconsejable, puesto que un simple cambio de nombre del control en la página origen provocaría un error en tiempo de ejecución, puesto que FindControl no sería capaz de encontrarlo con el nombre "TextBox1".

Hay otra forma mucho más potente, que consiste en especificar en la página destino un tipado fuerte para la de origen usando en su archivo .aspx la siguiente directiva:

<%@ PreviousPageType VirtualPath="~/PaginaOrigen.aspx" %>

De esta forma, cualquier referencia a PreviousPage en la página destino se considerará automáticamente del tipo de la página de origen, pudiendo acceder a sus propiedades de forma directa, sin necesidad de castings ni nada parecido. Sin embargo, todo sea dicho, debido a que el nivel de visibilidad de los controles de un Webform son protected, no podemos acceder directamente a su contenido, debemos usar accesores o propiedades públicas para ello.

Por ejemplo, podríamos definir en la clase (codebehind) de la página de origen una propiedad como la siguiente como accesor al contenido de un control TextBox llamado txtTexto:

public string Texto
{
get {return txtTexto.Text; }
}

Y en la página destino, una vez introducida la directiva descrita anteriormente especificando la URL de la página de origen, podríamos hacer lo siguiente:

if (PreviousPage != null)
{
Label1.Text = PreviousPage.Texto; // Por ejemplo
}

En resumen, esta técnica permite estructurar mucho mejor nuestras aplicaciones web, aunque sea a cambio de realizar un sobreesfuerzo en el desarrollo. En mi opinión puede valer la pena su uso en páginas que generen demasiadas vistas diferentes para ser introducidas en un único Webform sin comprometer la mantenibilidad, o cuando resulte interesante de cara a la reutilización de páginas.

No es conveniente, a mi entender, su utilización indiscriminada en formularios simples, pues precisamente los PostBacks fueron introducidos en ASP.Net para evitar la proliferación innecesaria de páginas sueltas (.aspx) y facilitar el mantenimiento del estado en la inherentemente desconectada tecnología Web.
jueves, 8 de noviembre de 2007
Leo en Codeville que Matt Gibbs (Program Manager de ASP.NET en Microsoft) ha anunciado hoy mismo, en el contexto de las conferencias TechEd que se están celebrando en Barcelona, que en las próximas semanas se publicará el primer CTP del ASP.NET MVC Framework.

Asimismo, se han vuelto a comentar las principales ventajas de utilizar este nuevo marco para el desarrollo de sistemas web:
  • Separación clara de lógica, presentación y control.
  • Utilización de URLs limpias y amigables.
  • Control absoluto sobre el marcado y emisión de XHTML puro.
  • Extensibilidad total, todos los componentes pueden ser reemplazados por otros de terceros.
  • Ventajas sobre Monorail (o incluso Ruby on Rails), como la perfecta integración con VS2008 (intellisense, plantillas, depuración...), o el uso de parte de la infraestructura ASP.NET (aunque se abandonen los postbacks).

En fin, que en breve tendremos diversión asegurada.
martes, 6 de noviembre de 2007
Días atrás, Daniel Moth, desarrollador de Microsoft, publicaba un interesante post comentando 10 puntos importantes a saber sobre el nuevo Visual Studio 2008 y .NET framework 3.5 y la verdad es que no tienen desperdicio.

1. Lanzamiento
Visual Studio 2008 y .NET framework 3.5 serán lanzados oficialmente juntos el próximo febrero. Sin embargo, estará disponible para desarrolladores a finales de noviembre de 2007.
Afortunadamente, estarán disponibles las versiones Express de C#, VB, C++ y Web, así como las Profesionales (¡con soporte de testeos unitarios!), Estándar y ediciones de equipos de desarrollo. La novedad será Visual Studio 2008 Shell, de carácter gratuito, que permitirá crear lenguajes y herramientas de desarrollo más verticalizadas.

Daniel comenta también que bajo Windows Vista, VS2008 será espectacular, e incluirá mejoras para la depuración de múltiples hilos. Ya no hay excusa para quedarnos con WXP ;-P

2. Compatibilidad hacia atrás
.NET framework 3.5 continúa la línea iniciada por Fx3.0 en cuanto al mantenimiento del CLR. Por tanto, y dado que lo único que hace es añadir ensamblados a las librerías presentes con las versiones 2.0 y 3.0 del framework, las aplicaciones actuales no se verán afectadas. Eso sí, necesitará los Service Packs 1 de ambas plataformas.

3. Generación multiplataforma
Visual Studio 2008 incluye la capacidad de crear proyectos para múltiples plataformas .NET, es decir, la 2.0, 3.0 y 3.5, desde el mismo entorno. Por tanto, no será necesario tener VS2005 instalado para generar ensamblados para .NET 2.0.

4. Multitud de novedades en C# 3.0 y VB9
Propiedades automáticas, delegados "relajados", inicializadores de objetos, inferencia de tipos, tipos anónimos, métodos de extensión, funciones lambda y métodos parciales, entre otros.

Pero no sólo eso... dado el punto 3 (generación multiplataforma), podremos usar estas nuevas características de nuestros lenguajes favoritos y generar para .NET 2.0.

5. LINQ
Se trata de una de las grandes revoluciones que nos aportará este nuevo conjunto de herramientas. Language INtegrated Query es un nuevo método de acceso a datos totalmente integrado en nuestro lenguaje habitual y de una forma muy independiente de la fuente de donde provengan (colecciones, XML, motores de bases de datos, etc.).

6. Novedades para ASP.NET
Visual Studio, así como el nuevo framework, ya incluirán ASP.NET AJAX de serie, así como 3 nuevos controles (ListView, DataPager y LinqDataSource). Además, el IDE ha sido muy mejorado e incluye soporte para intellisense y depuración de Javascripts, ¡también para ASP.NET 2.0!, y un nuevo diseñador que permite anidar páginas maestras.

7. Para el desarrollo en cliente
VS2008 incluirá nuevas plantillas de proyectos, así como un diseñador para WPF integrado con soporte para la comunicación WPF-WinForms. También se ha añadido el soporte para Firefox de la tecnología ClickOnce y XBAP (XAML Browser Applications).

8. Para el desarrollador de Office
Se ofrece soporte total para la personalizaciones (customisations) de Office 2007, así como para las plantillas de Office 2003.

9. Para desarrollo en servidor
Se han incluido nuevas plantillas para WCF y WF, y se han introducido mejoras interesantes en el primero, como el modelo de programación HTTP (sin SOAP) o serialización JSON.

10. Para el desarrollo en dispositivos móviles
Hay decenas de nuevas características, como el soporte para las versiones compactas de LINQ y WPF, o, a nivel de IDE, Unit Testing for Devices.

11. (punto extra) Código del framework
Pues sí, como ya es sabido, podremos depurar nuestras aplicaciones siguiendo el rastro por el interior de las clases y métodos del framework (como si no tuviéramos suficiente con las nuestras ;-)).

Más información en la fuente: The Moth.
lunes, 5 de noviembre de 2007
A raíz de un post anterior sobre scripts de arranque, y sobre todo en la relativa a la compartición del evento OnLoad por varios controladores, me ha llegado por varias vías la siguiente duda: ¿cómo se pueden vincular a este evento llamadas a funciones que incluyan parámetros?

Concretamente, gerardo pregunta cómo podría añadir varios controladores con parámetros al evento OnLoad de la página, como él mismo dice,

La funcion de script que usas para añadir varias funciones al evento onload esta bien si son llamadas sin parametros. La duda es cómo podría hacer lo mismo si la función que tiene que correr en el inicio recibiera un parametro de entrada.Siguiendo tu ejemplo, me gustaria usar algo como:

addOnLoad(init1(3));
addOnLoad(init2(4));


Efectivamente, la fórmula que propone este amigo no es válida; de hecho, estaríamos añadiendo al evento OnLoad el retorno de la llamada a init1(3), lo cual sólo funcionaría si esta función devolviera una referencia a una función capaz de ser invocada por el sistema.

Para hacerlo de forma correcta, como casi siempre en este mundo, hay varias formas. Comentaré algunas de ellas.

La obvia

Ni que decir tiene que el método más sencillo es sin duda introducir las llamadas en el atributo onload del elemento body de la página, es decir,

<body onload="alert('hola 1'); alert('hola 2');">
 
Por desgracia no siempre es posible modificar el atributo onload del cuerpo de la página, así que lo mejor será estudiar otras maneras.

La fácil

También podríamos utilizar un modelo bastante parecido al indicado en el post inicial, vinculando al OnLoad una función que, a su vez, llamará a las distintas funciones (con los parámetros oportunos) de forma secuencial:

// Asociamos las funciones al
// evento OnLoad:
addOnLoad(miFuncion1);
addOnLoad(miFuncion2);

function miFuncion1() {
alert('hola 11');
alert('hola 12');
}
function miFuncion2() {
alert('hola 2');
}
 

La "pro"

Aunque cualquiera de los dos métodos comentados hasta el momento son válidos y funcionan perfectamente, vamos a ver otra en la que se utiliza una característica de javascript (y otros lenguajes, of course), las funciones anónimas.

Las funciones anónimas son como las de toda la vida, pero con un detalle que la diferencia de éstas: no tienen nombre. Se definen sus parámetros y su cuerpo de forma directa en un contexto en el que pueden ser utilizados sin necesidad de indicar qué nombre vamos a darle.

En el caso que nos ocupa, y tomando como base el ejemplo anterior, en vez de invocar a la función addOnLoad() pasándole como parámetro el nombre de la función que contiene lo que queremos hacer, le enviaríamos una función anónima indicando exactamente lo que queremos hacer:

// En este código se hace lo mismo que
// el ejemplo anterior:

addOnLoad(
function() {
alert('hola 11');
alert('hola 12');
}
);
addOnLoad( function() { alert('hola 2'); } );
 
De esta forma la llamada a la función addOnLoad se realiza utilizando como parámetro la referencia a la función anónima, y todo puede funcionar correctamente.
viernes, 2 de noviembre de 2007
Unas semanas atrás escribía una entrada sobre Nifty Corners Cube, una librería javascript que permitía redondear las esquinas de los elementos de bloque de una web (como divs, h, etc.) sin necesidad de crear imágenes o hacer malabarismos con el marcado, sólo añadiendo unas referencias al archivo .js y algunos scripts básicos de inicialización.

Sin embargo, para un desarrollador habituado a arrastar y soltar, estas dos simples operaciones suponen demasiado esfuerzo como para considerar el uso de esta librería ;-), de ahí que me decidiera a crear NiftyDotNet.

NiftyDotNet es un componente para ASP.NET, escrito en C#, que encapsula todos los archivos y lógica necesarios para hacer funcionar Nifty Corners Cube en nuestras webs de una forma aún más fácil, simplemente arrastrando y soltando el control sobre nuestros webforms y ajustando unos sencillos parámetros, como el tamaño del borde o la selección de elementos a los que afectará.

Para que quede más claro, ahí va un ejemplo: observamos un formulario web en tiempo de diseño con un div central (que tiene un id='box1') y un control Nifty que afecta al mismo. A la derecha podemos ver también las distintas opciones de parametrización del control (puedes hacer clic sobre la imagen para ampliarla un poco):



Y continuación una captura con la página en tiempo de ejecución:



Como se puede ver, las esquinas del div central han sido redondeadas por el componente sin usar imágenes externas, sólo javascript no intrusivo. Increíble, ¿no? ;-)

El proyecto, publicado bajo GPL, se distribuye en tres paquetes, a elegir según el gusto y pretensiones del usuario:
  • Un ensamblado listo para ser utilizado en nuestros proyectos, o para añadirlo a la caja de herramientas (Toolbox) del entorno de desarrollo.
  • Una web de demostración, en la que podéis haceros una idea de la utilidad del componente. No hay una demo on-line debido a que en los servidores donde se encuentra no existe esta posibilidad, cuando encuentre un alojamiento apropiado la pondré para que pueda verse en vivo y en directo.
  • La solución VS2005 con el código fuente completo de ambos.

En la actualidad hay ya una versión bastante estable y depurada (a falta de comentarios de usuarios, claro!). Además, ha sido testeada tanto con Microsoft .Net Framework como con Mono, lo cual es siempre una buena noticia.

Por supuesto estaré encantado de recibir vuestras aportaciones, sugerencias, colaboraciones o comentarios de cualquier tipo.



Enlaces: