Eventos en Javascript

Introducción

En cada clase, estando en modo Admin, el administrador puede definir dentro de esta persiana, una lista de funciones que se ejecutan cada vez que se produce un evento del tipo: leer o modificar un campo, crear o eliminar un objeto de la clase actual, hacer login en la base... 

A cada clase se le aplican los eventos definidos en su propia clase y los de todas sus superiores. Por ejemplo, cualquier concepto de tareas preventivas (tarpre) también tiene en cuenta los definidos en Tareas (tar) y en la clase base general (con).

Especificación

Para la programación de eventos de una clase tenemos disponibles las siguientes funciones:

<campo>$Lee: function (bas,inc)
> valor sin formatear, para campos de tipo $ ajenos a la clase, similar al tarpre.texpro$ del cliente

<campo>Graba: function (bas,doc,val,cb)
> cb{error,fin,data,refresca} fin:interrumpe, error:interrumpe y presenta error data:agrega a grabación refresca:refresca ventana

<campo>Grabado: function (bas,tar,val0,cb)
> cb{error,refresca} val0: valor antiguo (el nuevo está en doc)

 

se pueden usar con val=doc[cod], que es el valor nuevo y val0 que es el que se ha reemplazado al editar, siendo cod el código del campo.

No se pueden usar funciones de grabación sin campo, para la grabación de cualquier campo de una clase, por ejemplo.

Hay otras funciones que no son contextuales a la ejecución en un sólo campo, son de creación y borrado de cualquier documento (doc):

elimina: function (bas,doc,cb) > cb{error|fin} fin:interrumpe, error:interrumpe y presenta error
eliminado: function (bas,doc,cb) > cb(error)
crea: function (bas,doc,cb) > cb{error|fin} fin:interrumpe, error:interrumpe y presenta error
creado: function (bas,doc,cb) > cb(error)

 

Consideraciones de uso

TODAS las funciones tienen que devolver siempre un callback, sino se produce un error que interrumpe la ejecución de eventos.

La Función bas.refresca() para grabar un dato sólo se puede utilizar en funciones previas a la grabación.

Los campos que son un paquete de objetos como las líneas de desglose de documentos (doc.linl), lista de medidas de Tareas y operaciones (tarpre.medl, tarcor.medl, ope.medl) y otros similares, no tienen accesibles para el cliente final los eventos de modificación / creación / borrado en cada campo de la lista, se graban como un paquete, como si fuese un campo entero.

La clase de tareas preventivas tarpre es un caso especial por sus eventos internos al crear automáticametne tareas (o abrirlas al eliminar las siguientes, etc.):
· Sólo está soportado el evento creado (no el crea)
· Sólo uso desde interface (internamente la función cierraTarea(), la cierraTareas() que se podría llamar en un script para cerrar masivamente, no lanza el evento de usuario

Ejemplos

Base de ejemplo: test-eventos

En esta base tenemos dos conjuntos de ejemplo principales:

1. Construcción de un sistema de trazabilidad de hitos en avisos mediante eventos con varias clases bajo carpetas car.eje1 y car.eje2.

2. Ejemplo de uso de los eventos habituales bajo la carpeta "car.eje3 · Ejemplo de eventos en conceptos y en campos de una clase".

En este ejemplo, en la  clase .inc (de incidencias) hay definidos eventos que se ejecutan antes de grabar el campo Observaciones técnicas (obstec) que es la función definida en obstecGraba, y después de grabar un texto en el campo, definido en obstecGrabado:

obstecGraba: function (bas,doc,val,cb) // sólo puede devolver error en el callback y en ese caso, interrumpe
{
  writeline("Antes de modificar las observaciones técnicas");
  return cb({error:'Interrupción del evento: por tanto, no se modifica el campo'});
  writeline("Nunca se muestra este mensaje, porque ya ha retornado error");
},
obstecGrabado: function (bas,doc,val,cb)
{
  writeline("No se ejecuta nunca Grabado, porque Graba devuelve error siempre");
  cb()
},

Al grabar el campo bin de un aviso, se pone en el campo espacio calle (espcal) del aviso el del bin; este campo no es editable manualmente. Se imprime también el pie el código de bin introducido. Si se elimina el dato (también es una modificación) no se hace nada:

binGraba: function(bas,doc,val,cb)
{
  writeline(val)
  if (!val) return cb()
  var bin= bas.doc2.docs[val]
  if (bin) return cb({data:{espcal:bin.espcal}})
  cb()
},
pad$Lee: function (bas,doc) // para rotular campos ajenos a esta tabla, similar al tarpre.texpro$ de cliente
{
  if (!doc.usu) return
  let usu= bas.doc2.docs[doc.usu]; if (!usu) return
  return usu.pad;
},
fechorGrabado: function (bas,doc,val,cb)
{
  writeline("Refresco de ventana tras grabar fechor")
  bas.refresca()
  cb()
},

Si en un par crea-creado, elimina-eliminado el primer evento no retorna con un callback, no se ejecuta el segundo:

crea: function (bas,doc,cb)
{
  writeline ("Antes de crear aviso: "+doc._id);
  cb() // sin este cb, no se ejecutaría creado:
},
creado: function (bas,doc,cb)
{
  writeline ("Tras crear aviso: "+doc._id);
  cb()
},

Depuración con Visual Studio Code

Para depurar el código javascript tanto de eventos como de procedimientos, recomendamos el entorno de desarrollo completísimo Visual Studio Code, de uso libre, que permite puntos de parada, examen de variables y funciones paso a paso, etc.

En la esquina superior derecha de la persianas de edición de código javascript tenemos el botón Graba 'eventos.htm', que permite guardar el contenido del programa actual en un archivo con el nombre del procedimiento en el directorio que deseemos. Se trata de una página independiente que se conecta a la BD con las credenciales actuales y se ejecuta como si fuese un cliente muy ligero, para probar los eventos que estamos programando contra la BD actual (o la que pongamos si cambiamos el parámetro).

Desde el entorno de desarrollo abrimos la carpeta donde hemos guardado el archivo y ejecutamos depuración de archivo en el navegador (admite Edge, Chrome y Firefox):

Clic para ampliar

 

El editor marca con colores oscuros las líneas, variables y parámetros no utilizados por el flujo de ejecución o porque no se hace referencia a ellos, detecta cualquier error de sintaxis es aperturas y cierres de llaves, corchetes, paréntesis... permite establecer puntos de parada y examinar muy visualmente los valores en ejecución, editar y reemplazar en bloque, usar recortes de código y muchísimas cosas más que facilitan la depuración de código javascript.

Eventos fijos programados en la aplicación

La aplicación ejecuta diversos eventos (también llamados triggers en otros motores de BBDD) en muchas clases: cuando se graban o borran datos en los campos, cuando de crean registros o se eliminar, etc. Esta página con tiene sólo los referentes a tareas preventivas y correctivas.

Si queremos reescribir estas funciones de eventos fijas en la aplicación hay que conocer en detalle lo que hacen para reproducirlo cuando añadamos nuestra funcionalidad y no romper la forma en la que opera el programa.

La función ingrid.eventos.tar() se ejecuta en ambas clases de tareas (preventias y correctivas), y luego cada una tiene una propia: