Noticias

Tips de la migración de win a web

Petroglifo, la edición de noticias de la empresa Concepto, publicó en su vigésima edición un artículo escrito por Alejandro Rinaldi, quien comparte su experiencia y algunos tips en la migración de aplicaciones GeneXus de Win a Web.

GUI (Grafic User Interfase): son las pantallas generadas con todos los generadores GeneXus para ambiente Windows.

Visualización GUI y WEB
El lenguaje base de las páginas web (HTML) no está definido estrictamente como en las pantallas GUI generadas con GeneXus. Por esta razón, la visualización de la aplicación difiere de acuerdo a la interpretación del código que realice el navegador utilizado.
En particular, en lo que atañe al diseño gráfico no se puede llegar a un nivel de precisión tan 'exacto' como en ambientes GUI. En ambientes HTML hay una diferencia entre cómo que se ve durante el desarrollo y lo que se verá en producción. Incluso una vez en producción la visualización del diseño varía según el navegador usado (Internet Explorer, Netscape, etc.)
La recomendación en este punto entonces, es no tomar este ambiente web como GUI y no intentar que se comporte como tal. Son ambientes distintos y con características distintas.

Manejo de eventos
En ambientes GUI se acostumbraba a diferenciar tres tipos de eventos:
-          Eventos que no trabajaban sobre ningún registro.
-          Eventos asociados a una línea
-          Eventos asociados a un grupo marcado con &op='X'


1-
Eventos sin líneas: un ejemplo clásico sería el de los botones de cerrar o agregar que se comportan igual sin importar qué línea esté seleccionada.
En ambiente Web se pueden dejar tal cual -que funciona bien- o sustituirlos por:

    1. Un control de texto con un link que se carga en el evento Start
    2. Una imagen con la propiedad clic o un evento asociado.

2- Eventos asociados a una línea: Por ejemplo, los botones de detalle modificar o eliminar. Al pasar al ambiente web, el navegador del cliente no puede saber cuál línea está seleccionada, ya no es posible seleccionar una línea como lo hacíamos que en el ambiente GUI. (La próxima versión Olimar de GeneXus actualmente en proceso de beta test- incluye facilidades para resolver esto). Para sustituirlos podemos:

a-     Eventos que llaman a otro WebPanel, o WebTRN pueden sustituirse por una nueva columna, con un texto o imagen que tenga un link que se cargue en el evento load de ese subfile. Por ejemplo, un botón de "detalle" puede reemplazarse por una columna con el texto "detalle" y link &detalle.Link =link (HDetalle, parametros) que se carga en el evento load de este subfile. 

b-     Eventos que llaman a un procedimiento o ejecutan algún código pueden reemplazarse por un evento "clic" en variables combobox o chekbox. De esta forma se obtiene un evento donde escribir nuestro código. Por ejemplo, llevar varios eventos a un solo combobox ( "Avanzadas")   

          
Event &Avanzadas.Click
         
Do case
         
case &Avanzadas ='A'   //'Algo ')
         
call(PAlgo, ATTClave) 
          
case &Avanzadas ='M'  //Modificar
         
call(TTransaccion, ATTClave,'UPD')
         
 &.

El case'se utiliza para seleccionar el evento. De esta forma se puede ejecutar cualquier código al igual que antes en un evento común. 

3-
    Eventos sobre más de una línea con un 'For Each line': El comando 'For Each line' funciona, basta con agregar sobre qué subfile se quiere trabajar, Por ejemplo, se puede agregar una figura en vez de un botón y un evento figura.clic

Event 'Sumar'
&
For each line In main

De esta forma la imagen tiene una propiedad que asocia un evento (sumar) al clic que se realice sobre esta imagen.  

Parámetros
En ambiente web no es posible conocer desde dónde se dio un clic para llegar a una página. Por ello, aunque la opción return'regresa a la página anterior, no se conoce el valor de las variables que se manejaban en la página previa. Para poder grabar variables de 'ambiente' hay varias opciones:

a- Grabar una cookie: Es fácil pero la cantidad de cookies está limitada y varía en los clientes. En el ejemplo del evento star se recupera una cookie con los valores de los parámetros 
            
            
&Param = GetCookie( 'MiCookie' )
           
&Viaje =val(substr( &Param ,1,8))
           
&Fecha =Ctod(Substr( &Param ,9,8))
           
&

y en el evento refresh'del subfile main se graba,

            &Param =str(&Viaje,8,0) + &Fecha
           
&OkCook =SetCookie( 'MiCookie' , &Param )

Aquí se graban todos los parámetros en una única cookie para minimizar la cantidad de éstas.

c-    Pasar las variables necesarias como parámetros a todos los WebPanels. Se recomienda encriptar dichos parámetros para ocultar su lógica.

d-    Tener una estructura en la base de datos con un identificador de sesión.

Style y Webcomponents
En ambiente Web no existen los Styles, eso es una gran desventaja con respecto a los WorkPanels, sin embargo tenemos una compensación que son los  WebComponents. Un Webcomponent es un objeto webpanel que sólo se diferencia de los demás por la posibilidad de ser agregado dentro de otro webpanel. Esto nos facilita la reutilización de código, que una misma funcionalidad puede ser 'importada' a un webpanel tantas veces como se necesite sin tener que repetir código. Esta herramienta es una diferencia fundamental y le da a este ambiente una ventaja con respecto a GUI que nos compensará la pérdida de los styles.

(nota: La versión Olimar de GeneXus incluirá una funcionalidad denominada "temas" que permite definir las propiedades de los controles de un form, y luego un objeto basado en ese tema.)

Generación dinámica
Mientras en ambiente GUI la pantalla se generaba totalmente de una sola vez y no en forma dinámica, es común que este cambio lleve a cometer algunos errores.
Por ejemplo, si se tiene una variable &cantidad que muestra la cantidad de registros que se despliegan en el subfile, para el ambiente Web pondríamos en el evento refresh un &cantidad=0 y en el evento load un &cantidad +=1. Aunque este cambio es correcto, si se pone la variable encima del subfile, ésta se desplegará siempre con un valor "0" sin importar la cantidad de registros que se lean. Esto se debe a que la parte de la pantalla que se muestra antes de cargar el subfile, se generó con anterioridad al procesamiento del subfile cuando la variable estaba en "0". Luego, al ejecutar el código que carga el subfile la variable toma el valor correcto pero ya es tarde pues nuestro evento se habra generado con el valor incorrecto.

Interacción con el usuario
En ambiente web no se puede interrumpir un procedimiento para pedir algún dato al usuario, por lo que luego quede iniciado el procedimiento no puede haber interacción gráfica. Para simular la confirmación de un evento, se puede poner un nuevo evento que haga visible o habilite el link que realmente ejecutará el proceso. Por ejemplo, si en un webpanel tenemos un combo box de "Ajustar Salida" que tiene el código siguiente en el evento clic del combo box:

case &Avanzadas ='S'  // 'Ajuste Salida')
confirmarOpcion.Visible =1 
&MiVariable.visible=1

Aquí se pone visible la imagen que realmente tiene el código ajustar a la salida.

Event 'Opcion'
call(PMiProceso , &MiVariable)
&MiVariable.visible=0
confirmarOpcion.Visible =0
Endevent

Así daremos la sensación de que se pidió una confirmación antes de ajustar la salida, aunque en realidad el procedimiento se llame en otro evento.

Call a webpanels
Un CALL (o LINK como comando) a un Web Panel es "asincrónico": mostrará este Web Panel cuando termine.  Por ejemplo, la ejecución de dos CALLs a Web Panels en un evento no provoca que ambos se ejecuten; sólo hace que el último llamado tome el "control" del navegador una vez terminado el código del llamador.
Por esta razón la programación tipo lista de selección no se utiliza. Por ejemplo en un evento "Seleccionar Matricula" que antes llamaba a un WKP WSMatricula y luego a un PRC PGMatricula que grababa la matrícula que se había seleccionado, ahora en ambiente web debería ser la lista de selección la que haga todo lo deseado.

call(HSMatriculayGraba , ATTClave)

En este caso en vez de llamar a WSMatricula y que éste regrese la matrícula seleccionada, para que un PRC grabe en la base. se la pasa el identificador de la línea para que sea la lista de selección que grabe la matrícula. Como consecuencia de ésto no se pueden reutilizar listas de selección y hay que tener un objeto distinto para cada vez que se necesite seleccionar una matricula.

Seguridad y acceso  
Para evitar el acceso a un workpanel si el usuario no tiene permisos, en ambientes GUI se ponía un control en un evento y como resultado se llamaba, o no, al workpanel restringido.

If &seguridad='S'
 
Call(Wdetalle, FacCliente)
Else
 
Msg(" no tiene permisos para ver el detalle del cliente")
Endif

Ahora aunque se puede habilitar o deshabilitar link en el evento load para no darle la opción si es que no le corresponde, también hay que controlar que el usuario no escriba la dirección URL directamente. En un ambiente web se podría escribir directamente la dirección de la página web y con los parámetros que quisiera. Esto puede ser controlado encriptando los parámetros y haciendo algún control en el evento start de la consulta.

 Event load
  If &seguridad='S'
  &detalle.link=link(hdetalle, FacCliente)
 endif

Petroglifo: http://www.concepto.com.uy/petrocsharp

Más información relacionada al tema:
Conversión de aplicaciones GUI a Web
Comparación GUI-WEB