Inicio > Desarrollo, Tutorial, Web > Razor, vistas y jQuery–solucionando la carga de componentes

Razor, vistas y jQuery–solucionando la carga de componentes

En la programación web moderna nos encontramos en algunas ocasiones con que necesitamos ejecutar determinados scripts cuando todo el contenido está cargado, y en casi todos los casos acabamos dependiendo de jQuery para ello. Es necesaria realmente esta dependencia?

En otro tiempo, cuando la programación web era mucho más directa y básica y no existían los frameworks de los que disponemos hoy en día, la solución era sencilla: cargas jQuery (posiblemente al principio de la página), luego todo el script que se necesita y, en algún lugar, posiblemente en el último script que cargas, se pone en ejecución el módulo principal de la aplicación. Sencillo, lineal, básico… hoy por hoy, completamente insuficiente.

Si vemos cualquier aplicación de hoy basada por ejemplo en MVC y Razor (o cualquier otro framework moderno similar), con infinidad de páginas parciales que se van ensamblando desde una página superior, se pierde totalmente el concepto de linealidad del que gozábamos antes. Ya no es “obvio” dónde hacer las cosas.

Vamos a fabricarnos un ejemplo para poner todo esto en contexto. Imaginemos una página que carga sus paneles por medio de vistas parciales (o incluso Ajax) dependiendo de las selecciones del usuario. Uno de esos paneles, que hemos definido en una vista parcial (vamos a emplear ASP.NET, MVC y Razor en nuestro ejemplo) contiene un par de selectores de fecha:

@{
    ViewData["Title"] = "Fechas de entrada y salida";
}

<div>
  <label>Fecha de entrada</label>
  <input class="datefield" id="DateIn" />
</div>

<div>
  <label>Fecha de salida</label>
  <input class="datefield" id="DateOut" />
</div>

<script>
  $(function ()
  {
    $(".datefield").datepicker();
  });
</script>

Típica vista parcial (muy simplificada), que añade ciertos campos y, por supuesto, usa jQuery para inicializarlos con una vista de calendario una vez se haya cargado el documento. El problema aquí es el pequeño fragmento de JavaScript del final. En otro tiempo, sabíamos en qué fase de carga de la página estamos, pero en nuestro ejemplo, con una vista parcial, no podemos ni siquiera saber si los scripts necesarios ya están cargados, o en qué orden se ha llamado a nuestra vista para incluir los contenidos en la página. De hecho, si seguimos los patrones recomendados hoy en día para cargar script, sólo se carga jQuery (o cualquier otra librería) después del cuerpo principal de la página, mucho después de invocar nuestra vista parcial. El resultado?

jQuery_not_found_1

Cuando se ejecuta nuestra parcial, jQuery ni siquiera está todavía cargado.

La solución habitual para este tipo de casos es, simplemente, cargar jQuery al principio de la página y todo resuelto: las parciales pueden usar $(function) (o “$.ready(function)). Pero y si ni siquiera usamos jQuery para los calendarios o usamos frameworks que no requieren jQuery? No es un poco absurdo cargar todo un framework solamente para una función?

Y si nos hacemos nuestro propio $.ready()?

Realmente no es nada difícil, ni tenemos que depender de un framework. Sólo necesitamos una función (que llamaremos ready(), para variar) que antes de terminar de cargar la página simplemente acumula llamadas a funciones y que, después de la carga, las ejecuta directamente. Una versión básica sería tan simple como esto:

(function ()
{
  var pending = [];
  window.ready = function (action)
  {
    pending.push(action);
  }

  window.addEventListener('load', function ()
  {
    pending.forEach(function (action)
    {
      action();
    });
    window.ready = function (action)
    {
      action();
    }
  });
})();

Sencillo, no? Vale, un poco largo para ponerlo al principio de la página, pero si minimificamos (se escribe así?) quedaría como una sola línea (y ni siquiera larga) que incluso nos ahorra una petición extra si no la cargamos como un script externo:

<script>(function(){var n=[];window.ready=function(t){n.push(t)};window.addEventListener("load",function(){n.forEach(function(n){n()});window.ready=function(n){n()}})})();</script>

Si colocamos ese fragmento de script al principio de nuestras páginas (en el elemento HEAD), eventualmente en nuestra página de layout principal (_Layout.cshtml en jerga Razor), sin ni siquiera cargarlo desde un archivo separado, todo se vuelve mucho más fácil: podemos cargar (en nuestro ejemplo) tanto jQuery como jQuery.UI desde cualquier otro lugar que consideremos oportuno, y todo simplemente funciona:

<script>
  ready(function ()
  {
    $(".datefield").datepicker();
  });
</script>

De hecho, y si utilizamos la nueva sintaxis para escribir funciones (soportado por los navegadores modernos), queda incluso más bonito:

<script>
  ready(() => $(".datefield").datepicker());
</script>

El precio? Aproximadamente 180 bytes al principio de nuestras páginas, sin cargar ningún elemento externo ni depender de un framework cargado previamente. Y nuestro código, más limpio y fácil de mantener.

Anuncios
Categorías:Desarrollo, Tutorial, Web Etiquetas: , , , , ,
  1. Aún no hay comentarios.
  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

A %d blogueros les gusta esto: