JQuery reactivo para bases de código heredadas espaguetis (o cuando no puedes tener cosas buenas)

Puedo oírte gritar ahora: “¿Por qué querrías usar jQuery cuando hay herramientas muchas mejores disponibles? ¡Locura! ¿Qué clase de maníaco eres? Estas son preguntas razonables y las responderé con un poco de contexto.

En mi trabajo actual, soy responsable del cuidado y alimentación de un sitio web heredado. Es viejo. La interfaz se basa en jQuery y, como la mayoría de los sistemas antiguos, no está en la mejor forma. Eso por sí solo no es lo peor, pero estoy trabajando con limitaciones adicionales. Por ejemplo, estamos trabajando en una reescritura completa del sistema, por lo que no se aprueba un trabajo de refactorización masiva y tampoco se me permite agregar nuevas dependencias al sistema existente sin una revisión de seguridad completa, que históricamente puede llevar hasta un año. Efectivamente, jQuery es la única biblioteca de JavaScript que puedo usar, ya que ya está ahí.

Mi empresa se ha dado cuenta recientemente de que los desarrolladores de aplicaciones para el usuario pueden tener habilidades importantes que aportar, por lo que toda la interfaz de la aplicación fue escrita por desarrolladores que desconocían las mejores prácticas y, a menudo, despreciaban su tarea. Como resultado, la calidad del código es tremendamente desigual y bastante pobre y poco idiomática en general.

Sí, trabajo en ese código base heredado: los espaguetis jQuery por excelencia.

Alguien tiene que hacerlo, y dado que siempre habrá más código heredado en el mundo que proyectos nuevos, siempre seremos muchos de nosotros. Tampoco quiero tu simpatía. Lidiar con estas cosas y aprender a lidiar con espaguetis de front-end a una escala tan masiva me ha convertido en un mejor desarrollador, aunque más irritable.

Entonces, ¿cómo sabes si tienes spaghetti jQuery en tus manos? Un olor a código confiable que he encontrado es la falta del venerable código antiguo .toggle(). Si ha logrado no pensar en jQuery por un tiempo, es una biblioteca que soluciona los problemas de compatibilidad entre navegadores y al mismo tiempo hace que las consultas y mutaciones DOM sean increíblemente fáciles. No hay nada intrínsecamente malo en eso, pero la manipulación directa del DOM puede ser muy difícil de escalar si no se tiene cuidado. Cuanta más manipulación DOM escribas, más a la defensiva te volverás contra la mutación DOM. Con el tiempo, puedes encontrarte con una base de código completa escrita de esa manera y, combinado con una administración del alcance no tan ideal, básicamente estás trabajando en una aplicación donde todo el estado está en el DOM y nunca puedes confiar en el estado del DOM. estará presente cuando necesite realizar cambios; Los cambios podrían ocurrir desde cualquier lugar de su aplicación, le guste o no. Su código se vuelve más procedimental, inflando las cosas con instrucciones más explícitas, tratando de extraer todos los datos que necesita del propio DOM y forzarlos a entrar en el estado que necesita.

Por eso, .toggle()a menudo es lo primero que hay que hacer: si no puedes estar seguro de si un elemento es visible o no, tienes que usar .show()y .hide()en su lugar. No estoy diciendo .show()que .hide()deban considerar perjudiciales™, pero he descubierto que son un buen indicador de que podría haber problemas mayores en marcha.

¿Qué puedes hacer para combatir esto? Una solución que hemos encontrado mis compañeros de trabajo y yo toma una pista directamente de los marcos reactivos que preferiríamos usar: observables y gestión de estado. Todos hemos descubierto que los objetos de estado móviles y las funciones de actualización basadas en eventos, mientras tratamos nuestro DOM como una plantilla de flujo de datos unidireccional, conducen a resultados más predecibles que son más fáciles de cambiar con el tiempo.

Cada uno de nosotros aborda el problema de manera un poco diferente. Mi versión de jQuery reactivo tiene un sabor distintivo como el de Vue y aprovecha algo de CSS “avanzado”.

Si revisas el guión, verás que suceden dos cosas diferentes. Primero, tenemos un Stateobjeto que contiene todos los valores de nuestra página y tenemos una gran cantidad de eventos.

var State = {  num: 0,  firstName: "",  lastName: "",  titleColor: "black",  updateState: function(key, value){    this[key] = value;            $("[data-text]").each(function(index, elem){      var tag = $(elem).attr("data-tag");      $(elem).text(State[tag]);    });        $("[data-color]").each(function(index, elem){      var tag = $(elem).attr("data-tag");      $(elem).attr("data-color", State[tag]);    });  }};

Lo admito, me encantan los atributos HTML personalizados y los he aplicado generosamente en toda mi solución. Nunca me ha gustado cómo las clases HTML a menudo cumplen una doble función como enlaces CSS y enlaces JavaScript, y cómo si usas una clase para ambos propósitos a la vez, ha introducido fragilidad en tu script. Este problema desaparece por completo con los atributos HTML. Las clases vuelven a ser clases y los atributos se convierten en cualquier metadato o gancho de estilo que necesite.

Si observa el HTML, encontrará que cada elemento en el DOM que necesita mostrar datos tiene un data-tagatributo con un valor que corresponde a una propiedad en el Stateobjeto que contiene los datos que se mostrarán y un atributo sin valor. que describe el tipo de transformación que debe ocurrirle al elemento al que se aplica. Este ejemplo tiene dos tipos diferentes de transformaciones, texto y color.

h1 data-tag="titleColor" data-colorjDux is super cool!/h1

A los acontecimientos. Cada cambio que queremos hacer en nuestros datos es provocado por un evento. En el script, encontrará todos los eventos que nos preocupan enumerados con su propio .on()método. Cada evento activa un método de actualización y envía dos datos: qué propiedad del Stateobjeto debe actualizarse y el nuevo valor en el que se debe establecer.

$("#inc").on("click", function(){  State.updateState("num", State.num + 1)});$("#dec").on("click", function(){  State.updateState("num", State.num - 1)});$("#firstNameInput").on("input", function(){  State.updateState("firstName", $(this).val() )});$("#lastNameInput").on("input", function(){  State.updateState("lastName", $(this).val() )});$('[class^=button]').on("click", function(e) {  State.updateState('titleColor', e.target.innerText);});

Esto nos lleva a State.updateState(), la función de actualización que mantiene su página sincronizada con su objeto de estado. Cada vez que se ejecuta, actualiza todos los valores etiquetados en la página. No es lo más eficiente rehacer todo en la página cada vez, pero es mucho más simple y, como espero haber dejado claro, esta es una solución imperfecta para una base de código imperfecta.

$(document).ready(function(){  State.updateState();});

Lo primero que hace la función de actualización es actualizar el valor según la propiedad que recibe. Luego ejecuta las dos transformaciones que mencioné. Para los elementos de texto, crea una lista de todos data-textlos nodos, toma su data-tagvalor y establece el texto en lo que esté en la propiedad etiquetada. El color funciona de forma un poco diferente: establece el data-coloratributo en el valor de la propiedad etiquetada y luego se basa en el CSS, que aplica estilo a las data-colorpropiedades para mostrar el estilo correcto.

También agregué un document.ready, para que podamos ejecutar la función de actualización al cargar y mostrar nuestros valores predeterminados. Puede extraer valores predeterminados del DOM, o una llamada AJAX, o simplemente cargar el objeto Estado con ellos ya ingresados ​​como lo hice aquí.

¡Y eso es! Todo lo que hacemos es mantener el estado en JavaScript, observar nuestros eventos y reaccionar a los cambios a medida que ocurren. Sencillo, ¿verdad?

¿Cuál es el beneficio aquí? Trabajar con un patrón como este mantiene una única fuente de verdad en su objeto de estado que usted controla, en el que puede confiar y que puede hacer cumplir. Si alguna vez pierde la confianza en que su DOM es correcto, todo lo que necesita hacer es volver a ejecutar la función de actualización sin argumentos y sus valores volverán a ser consistentes con el objeto de estado.

¿Es esto un poco tonto y primitivo? Absolutamente. ¿Le gustaría construir un sistema completo a partir de esto? Ciertamente no. Si tiene mejores herramientas disponibles, debería utilizarlas. Pero si se encuentra en una base de código heredada altamente restrictiva como la mía, intente escribir su próxima función con jQuery reactivo y vea si simplifica su código y su vida.

SUSCRÍBETE A NUESTRO BOLETÍN 
No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion