Sie sind auf Seite 1von 42

PRIMEROS PASOS EN ROBOTLEGS + ZEND + PHP +

POSTGRESQL
Marcelo Jingo 03-2012
Ver 1

2


3

Contenido
1. Crear Proyecto .................................................................................................................................................................... 4
2.- Instalar RobotLegs ............................................................................................................................................................. 5
3. Crear los packages necesarios ............................................................................................................................................ 5
4. Primer Componente Visual ................................................................................................................................................. 5
6. Crear el mediador ............................................................................................................................................................... 6
7. Crear Comandos .................................................................................................................................................................. 8
8. Crear el Modelo ................................................................................................................................................................ 10
9. Crea la clase con Eventos .................................................................................................................................................. 10
10.- Crear el Contexto.- ......................................................................................................................................................... 11
11. Referenciar el contexto dentro de Aplicattion ............................................................................................................... 12
12. Crear la estructura de ZendFramework .......................................................................................................................... 12
13. Crear modelos con Zend_db .......................................................................................................................................... 14
14. Usando los Serviciosdesde Flash Builder ........................................................................................................................ 19
15.- Redisear el Datagrid ..................................................................................................................................................... 23
TIPS a tomar en cuenta ......................................................................................................................................................... 26
Campos NULOS ................................................................................................................................................................. 26
Error Obtenido: select the local resource that matches the following server path ..................................................... 26



4

Proyecto usando RobotLegs
El RobotLegs es un framework de actionscript
Est compuesto de 4 clases principales que son: Mediator, Command, Actor y Context
1. Crear Proyecto.- Creo el proyecto FLEX-PHP con
File-New-Flex and PHP Project

Para asegurarnos que el webroot es vlido dar click en "ValidateConfiguration" eso comprueba que est bien los
servicios web y de php.
Dar click en Next para crear el proyecto Flex, nos aparece el siguiente cuadro de dilogo

Pulsamos "Finish" y se crear la estructura de nuestros 2 proyectos de PHP (que estar ubicado en el webroot) y el de
PHP que estar en otra ruta (la de flash). Pero en el entorno de trabajo de Flash lo veremos as:
5


2.- Instalar RobotLegs.- Bajar el robotlegs de http://www.robotlegs.org, que en este momento est en la
versin 1.5.2.
copiamos en la carpeta libs de nuestro proyecto el archivo robotlegs-framework-v1.5.2.swc, que se encuentra en la
carpeta bin del archivo previamente descargado.
3. Crear los packages necesarios.- Dentro del proyecto Flex, crear en la carpeta o package "src" las
siguientes packages: comands,events,model y views. Dando click derecho sobre "src" seleccionar: New-Package, lo que
nos da el siguiente cuadro de dialogo donde ingresaremos el nombre de mi nueva carpeta:

As lo haremos con todas hasta obtener la siguiente estructura

4. Primer Componente Visual.- Creamos un componente visual en la carpeta "views" que va a contener un
boton y un datagrid. Procedemos as: dar click derecho en "views" y seleccionar New-MXML Component, y en el cuadro
de dilogo que aparece ingresamos el nombre del componente "ListaView" (En el grfico aparece como VerLista porque
es de otro ejemplo), y luego de aceptar diseamos nuestra vista con los elementos mencionados:
6


El datagrid no lo enlazamos con ningn modelo. Es ms lo podemos dejar sin datos iniciales. Pero s es importante que el
nmero de columnas que tenga el datagriddebe ser el mismo que el que devuelva el servicio que llenar nuestra tabla.
Como an no creamos los modelos ni servicios de php para mapearlos en Action Script, dejemos el datagrid as tal cual.
En el punto 15 retomamos para cambiarlo a como finalmente debe quedar.
5. Generar Eventos que atrapa el mediador. Ahora vamos a editar el cdigo fuente de este
componente y en la parte del botn vamos a aadir la etiqueta click, que indica qu har el botn cuando pulsemos
sobre l. En este caso se va a desencadenar un evento que ser atrapado por el mediador de este componente.

El cdigo queda as:
<s:Button x="56" y="45" label="Cargar Datos"
click="dispatchEvent(new Event("CARGA_DATA"))"/>
Aqu vemos que se crea el evento que le hemos dado el nombre CARGA_DATA, el cual podr ser escuchado en la clase
mediador.
El mediador que est siempre escuchando, atrapa el evento para despacharOTRO evento que desencadena la ejecucin
de un comando
En la prctica lo mejor es crear primero las clases del modelo (punto 8) y de los eventos (punto 9) en sus
respectivas carpetas. Esto permitir incluirlos en el mediador sin obtener errores;el modelo es extendida
de Actor y eventos no se extiende de nada, en esta ltima declaramos las constantes de los eventos.
Porque estos sern incluidos en las otras clases.
6. Crear el mediador.- Ahora vamos a crear el mediador, que no es ms que una clase extendida de la clase
Mediator del robotlegs, que interacta con el componente visual para actualizarlo ;y la vamos a ubicar en la carpeta
views, haciendo click derecho y seleccionando New - ActionScriptClass.
7


Lo importante en esta clase es que debemos declarar atributos (variable) tipo [inject] que hace referencia a la vista o al
modelo (Que ya deben estar creados, punto 8 y9), que en este caso quedara:
[Inject]
publicvarview:ListaView;

Luego de definirse el mtodo constructor"sobreescribimos" el mtodo onRegister que registra a los escuchadores tanto
de los componentes visuales que en este caso escuchara para capturar los eventos que ocurran en "ListaView", as como
de los dems actores. Aqu en este mtodo colocamos todos los eventos que los componentes grficos despacharn.



overridepublicfunctiononRegister():void
{
addViewListener("CARGA_DATA", sendRequest);
addContextListener(CountryListEvents.TABLA_DATA_CARGADO, dataLoadedHandler);
}

Aqu vemos que el escuchador registra el evento CARGA_DATA despachado por el botn del componente visual
"ListaView", y en ese mismo momento despacha un nuevo evento mediante el mtodo sendRequest (declarado ms
abajo) ese evento se denomina CARGA_TABLA_DATA lo cual provoca que se ejecute el mtodo execute del comando
"CargaTablaData" asociado a ese evento. Esa asociacin la encontramos en la otra parte de RobotLegs representado por
la clase denominada context que lo veremos ms adelante.
privatefunctionsendRequest(event:Event):void
{
dispatch(new Event(CountryListEvents.CARGA_TABLA_DATA));
}

Regresando al mtodo onRegister en su segunda sentencia se registra tambin el evento del Context que se lo
denomina TABLA_DATA_CARGADO que provocar que se ejecute dataLoadedHandler, ste actualiza el datagrid del
componente visual con los datos cargados (desde el comando) en la variable del modelo que es de tipo arraycollection.
privatefunctiondataLoadedHandler(event:Event):void
8

{
view.GridGen.dataProvider = applicationModel.tablaList;
}

El cdigo completo queda:
packageviews
{
importevents.ListEventos;


importflash.events.Event;

importmodel.ListModelo;

importorg.robotlegs.mvcs.Mediator;

publicclassListaMediadorextends Mediator
{
[Inject]
publicvarview:ListaView;

[Inject]
publicvarapplicationModel:ListModelo;
publicfunctionListaMediador()
{
super();
}
overridepublicfunctiononRegister():void
{
addViewListener("CARGA_DATA", sendRequest);
addContextListener(ListEventos.TABLA_DATA_CARGADO, dataLoadedHandler);
}

privatefunctionsendRequest(event:Event):void
{
dispatch(new Event(ListEventos.CARGA_TABLA_DATA));
}


privatefunctiondataLoadedHandler(event:Event):void
{
view.GridGen.dataProvider = applicationModel.tablaList;
}

}
}
7. Crear Comandos.- Ahora nos toca crear el comando o clase CargaTablaData, que hereda de la clase command
del robotlegs.Lo crearemos siguiendo los mismos pasos que en el punto 6, pero dentro de la carpeta commands.
Es el que se encarga de obtener los datos de una fuente determinda usando el servicio respectivo. Vea como [inject]
inyecta una referencia vlida del servicio y el modelo cuando se crea un objeto de la clase CargaTablaData.
Luego se crea un objeto del tipo CallResponder, que es el que permitir realizar los accesos remotos a la base de datos
usando los servicios creados (ver punto 14).
9

En el commandCargaTablaData tenemos el mtodo "execute" en donde se registra un evento que ser de tipo respuesta
(CallResponder), especficamente de tipo RESULT, es decir este evento suceder cuando la llamada obtenga un
resultado, y es en ese momento que debe desencadenar a la funcin que en mi caso lo he llamado
Manejador_de_Resultado, dentro de sta es donde se carga el resultado en la variable tablaList de tipo ArrayCollection
que fue inicializada en el Modelo "ListModelo", ese resultado corresponde al obtenido en el token mediante la llamada
al servicio "getAllProyectos()" definido en los servicios creados cuando se crea una conexin a un tipo de datos (punto
14).
Recuerde que esta clase es mapeada en el contexto ListaContext en donde se le indica qu evento le corresponde para
desencadenar este comando que hemos generado.
packagecommands
{
importmodel.ListModelo;

importmx.collections.ArrayCollection;
importmx.rpc.CallResponder;
importmx.rpc.events.FaultEvent;
importmx.rpc.events.ResultEvent;

importorg.robotlegs.mvcs.Command;

importservices.proyectoserv.ProyectoServ;

importvalueObjects.Proyectos_vo;

publicclassCargaTablaDataextends Command
{
[Inject]
publicvarapplicationModel:ListModelo;

[Inject]
publicvarservice:ProyectoServ;

publicfunctionCargaTablaData()
{
super();
}

privatevarrespuesta:CallResponder = newCallResponder();

overridepublicfunction execute():void{
respuesta.addEventListener(ResultEvent.RESULT, Manejador_de_Resultado);
respuesta.token = service.getAllProyectos();
}

privatefunctionManejador_de_Resultado(event:ResultEvent):void{

//tablalist es un arraycollection donde se cargan los datos
//La variable est definida en el modelo
applicationModel.tablaList = respuesta.lastResult ;
//se actualiza el modelo, lo que provoca se despache el evento de "datos
cargados"
//Ese evento es atrapado en el mediador que hace que actualice la vista
}

}
}
10


8. Crear el Modelo.- Creamos la representacin del modelo llamndolo ListModelo, que es una clase extendida
de la clase Actor del robotlegs a la que se le aade funciones bsicas para comunicarse con los dems actores. Guarda
los datos .Seguiremos los mismos pasos anteriores, pero sobre la carpeta model. Creamos una variable que guarde los
datos a tratar, en este caso creamos una variable de tipo ArrayCollection, que me permitir almacenar los registros de la
tabla devueltos por el servicio como conjunto de objetos. Aqu encontraremos las funciones get() y set()..... Cuando se
hace un set() o modifica la variable se despacha un evento que lo he llamado TABLA_DATA_CARGADO, que me indica
que se han cargado datos, dicho evento ser atrapado por el mediador, el cual acto seguido enviar a actualizar el
componente visual datagrid (ver punto 6).
package model
{
importorg.robotlegs.mvcs.Actor;
importflash.events.Event;
importmx.collections.ArrayCollection;
importevents.ListEventos;

publicclassListModeloextends Actor
{
publicfunctionListModelo()
{
super();
}

privatevar _tablaList:ArrayCollection;
publicfunctiongettablaList():ArrayCollection
{
return _tablaList;
}
publicfunctionsettablaList(value:ArrayCollection):void
{
_tablaList = value;
dispatch(new Event(ListEventos.TABLA_DATA_CARGADO));
}

}
}

9. Crea la clase con Eventos.- Crear la clase de los eventos donde definimos las constantes o nombres que les
daremos a nuestros eventos.
package events
{
publicclassListEventos
{
publicfunctionListEventos()
{
}
publicstaticconstCARGA_TABLA_DATA:String = "CARGA_TABLA_DATA";
publicstaticconstTABLA_DATA_CARGADO:String = "TABLA_DATA_CARGADO";
}
}
11


10.- Crear el Contexto.- Ahora dentro de la carpeta por defecto "src" (default package) vamos a crear la clase
ListContext que se extiende de la clase Context de robotlegs. Aqu mapeamos todos los objetos a usarse, como el
componente visual y su mediador. Aqu definimos el mecanismo de inyeccion (singlenton) de las variables de por
ejemplo el modelo y el servicio, y cuyas referencias sern inyectadas en el modelo y servicio.
As tambin se indica qu evento se corresponde a qu comando, en nuestro ejemplo se define que para el evento
CARGA_TABLA_DATA corresponde el comando CargaTablaData;
Se establece cual es el mediador del componente visual, esto provocar que cuando se aada el componente visual, se
crear una instancia de la clase ListaMediador, se inyectarn sus dependencias y se invocar el mtodo onRegister
del mediador(punto 6).
Para mapear objetos en el contexto solo hay que definir qu tipo de mapeo haremos. Existen varios tipos, utilizaremos
los 3 mas ocupados
Para mapear los datos de Modelos y de Servicios utilizaremos injector
Para los componentes visuales y sus mediadores utilizaremos viewMap
Y por ultimo para registrar eventos con comandos se harn con commandMap.

package
{
importcommands.CargaTablaData;

importevents.ListEventos;

importflash.display.DisplayObjectContainer;

importmodel.ListModelo;

importorg.robotlegs.mvcs.Context;

importservices.proyectoserv.ProyectoServ;

importviews.ListaMediador;
importviews.ListaView;

publicclassListaContextextends Context
{
publicfunctionListaContext(contextView:DisplayObjectContainer=null,
autoStartup:Boolean=true)
{
super(contextView, autoStartup);
}

overridepublicfunction startup():void{

//Mecanismo de inyeccin. Que luego sern inyectadas
//en el mediador y en el comando segn sean necesarios.
injector.mapSingleton(ListModelo);
injector.mapSingleton(ProyectoServ);
12


//Indicamos los pares "evento-comando" es decir que
//para el evento CARGA_TABLA_DATA corresponde el comando CargaTablaData
//Cuando alguien despache CARGA_TABLA_DATA se crea un objeto
CargaTablaData (y por ende ejecuta execute)
commandMap.mapEvent(ListEventos.CARGA_TABLA_DATA, CargaTablaData);

//establece al componente visual con su mediador (la clase mediator)
mediatorMap.mapView(ListaView, ListaMediador);
}

}
}

11. Referenciar el contexto dentro de Aplicattion.- Creamos el contexto en la Aplicattion. Lo que
hacemos en esta parte es iniciar la clase dentro de nuestra aplicacin.
<?xml version="1.0" encoding="utf-8"?>
<s:Applicationxmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
xmlns:local="*" xmlns:views="views.*">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<local:ListaContextcontextView="{this}"/>
</fx:Declarations>
<views:ListaView/>
</s:Application>
An no ejecutemos el proyecto, construyamos los datos
12. Crear la estructura de ZendFramework.- En este punto olvidemos por un momento el RobotLegs y
vamos a crear la estructura del ZendFramework para hacer uso de los servicios php para el acceso a la base de datos.
No olvidemos que ya tenemos creados nuestros dos proyectos Flex y Php mediante Flash Builder, y la estructura que
tenemos de esos proyectos es la siguiente:

13

Bien , ahora sobre la estructura del proyecto PHP vamos a regenerar esa estructura usamos las zendtools integrado en
Flash Builder mediante el comando: zf createproject UsandoRL_P
Siga la siguiente secuencia: click derecho sobre el proyecto ->ZendTool y aparecer el cuadro de comandos de Zend: All
ingresamos los comandos que posteriormente usaremos.

Como ven lo que creamos es el proyecto zend usando el mismo nombre de nuestro ya creado proyecto php, esto nos
genera la nueva estructura creando las nuevas carpetas aplication, docs y tests tal como vemos a continuacin:

Recuerde que en la carpeta services del proyecto PHP colocaremos nuestras clases en php con los mtodos o servicios
para el acceso a la Base de datos.
Ahora que hemos aumentado la estructura de los directorios de nuestro proyecto con Zend se crea un archivo index.php
en la raz de /public, si accedemos desde el navegador a sta carpeta haciendo :http://localhost/UsandoRL_P/public
se obtiene esta pantalla

Esto nos permite comprobar que zend est funcionando. Pero la aplicacin no va a estar aqu, pues no vamos a usar las
vistas o el Front_end con zend sino vamos a usar al Flash Builder. Es as que cuando mandamos a correr la Aplicacin
desde Flash, lo que hace ste es generar lo archivos necesarios (compilar) y colocarlos en esta misma carpeta de php
pero un nivel ms adelante, es decir en nuestro caso la aplicacin estar en: http://localhost/UsandoRL_P/public/bin-
debug
aqu encontraremos el archivo "UsandoRL_.php" (en mi caso) que ser la entrada a la aplicacin.
Vamos a comprobarlo, para ello an no voy a usar los lineamientos de Robotlegs porque hay que adicionar algunas
cosas a la aplicacin principal. Es decir que an no vamos a hacer nada que implique a RobotLegs en el cdigo de
14

"UsandoRL_F.mxml" que est en el proyecto de flex. Lo que vamos a incrementar (para luego borrarlo) es simplemente
un botn con algn mensaje. Entramos a modo de diseo e incorporamos el boton. Y el cdigo va a quedar as:
<?xml version="1.0" encoding="utf-8"?>
<s:Applicationxmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955"
minHeight="600">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Button x="121" y="121" label="Pulsame"/>
</s:Application>

Ahora procedamos a ejecutar la aplicacion desde Flash y debe abrir una ventana del navegador mostrando el resultado.

Si miramos en el cuadro de la URL vemos claramente la direccin la que se ejecuta, puede hacerlo ingresando
manualmente que le dar el mismo resultado.
Comprobado esto vamos a quitar el botn y dejarlo como estaba inicialmente.
13. Crear modelos con Zend_db.- Vamos a crear ahora los modelos y ValueObjects con Zend_db (mapeo
de las tablas que vamos a usar).
Activemos el cuadro de comandos de ZendTools tal como lo hicimos anteriormente.
a. Configuremos la conexin.
Lo primero que vamos a hacer es configurar la conexin agregando un adaptador de Base de Datos mediante el
siguiente comando:
zf configure dbadapter "adapter= PDO_PGSQL&username= postgres&
password=postgres&dbname=gpi_gestion"

Esto lo que hace es crear un archivo de configuracin denominado application.ini que se guarda en la carpeta
application/configs de nuestro proyecto PHP. Si despus queremos cambiar de Motor de Base de Datos solo
modificamos este archivo.

15



b. Crear los modelos
Ahora ya podemos generar los modelos de todas las tablas de nuestra base de datos, aunque no genera un
modelo completo, porque no es un ORM, pero si crea un esqueleto, y para ello ejecutar:
zf create db-table Proyectos gpi_proyectos.proyectos
En donde
- Proyectos es el nombre del modelo o clase que se crear en la carpeta Application/models/DbTable
- gpi_proyectos.proyectoses el nombre de la tabla en la base de Datos (porque tenemos la tabla dentro de un
esquema).
Este archivo creado en la carpeta models/DbTable: Proyectos.php ser la clase que se hereda de
Zend_Db_Table_Abstract que permitirn mediante sus mtodos tener acceso a la tabla. Su contenido es
algo como esto:
<?php

classApplication_Model_DbTable_Proyectosextends Zend_Db_Table_Abstract
{
protected$_name = 'gpi_proyectos.proyectos';
}

Y veamos como se ha creado en la vista de Flash Builder:



c. Crear los ValueObject
Esta clase php me permitir mapear los registros de la tabla desde la clase PHP hacia la clase Action Script y
sern los ValueObjects. Estos archivos php los ubicamos en la carpeta "services" del proyecto PHP (BAKCEND),
en su interior se define los campos de la tabla y su tipo que deben corresponder. El contenido de estos archivos
automatiza la inicializacin para losValueObjects de AS.
Podemos crear el archivo dando click derecho sobre la carpeta services y ejecutar New -> PHP File, y all ingresar
el cdigo correspondiente.
El archivo "proyectos_vo.php" queda as:
<?php
classproyectos_vo
16

{
/**
* @varint
*/
public$proyecto_id ;
/**
* @var string
*/
public$proyecto_codigo ;
/**
* @varstring
*/
public$proyecto_nombre ;
/**
* @var Date
*/
public$creado;
/**
* @var string
*/
public$creadopor;
/**
* @var Date
*/
public$actualizado;
/**
* @var string
*/
public$actualizadopor;
/**
* @varint
*/
public$institucion_id ;
/**
* @varint
*/
public$tipoproyecto_id;
/**
* @varint
*/
public$organizacionint_id;


public function __construct()
{
$this->proyecto_id = 0;
$this->proyecto_codigo="";
$this->proyecto_nombre="";
$this->creado=date("c");
$this->creadopor="";
$this->actualizado=date("c");
$this->actualizadopor="";
$this->institucion_id=0;
$this->tipoproyecto_id=0;
$this->organizacionint_id=0;
}
}

d. Crear los Servicios o Mtodos
17

Son los mtodos que servirn para el acceso a la Base de Datos y se crearan en la misma carpeta "services" del
proyecto php, con ellos podemos insertar, modificar o eliminar.

El archivo que contendr las funciones para el acceso a la tabla lo llamar proyectoServ.php.
<?php
//incluimos la clase que servir para
//configurar los tipos de datos de la tabla
include_once'proyectos_vo.php';

ClassproyectoServ
{
protected$proyectos;

publicfunction__construct ()
{
$this->proyectos = new Application_Model_DbTable_Proyectos();
}

/**
* Leer un solo registro de las proyectoss
* @paramint $id
* @returnproyectos_vo
*/
public function getproyectosByID ($id)
{
$sel="SELECT * FROM gpi_proyectos.proyectos where proyecto_id=$id";
$res= $this->proyectos->getAdapter()- >fetchRow($sel);//fetchAll()-
>toArray();//('SELECT * FROM area where cod_area='.$id);
$data=print_r($res,true);

//Antes de devolver los datos los pasamos a una variable tipo objeto con la
estructura
//de la tabla, acorde con los tipos de datos que se debe entregar
$proy = new proyectos_vo();

$proy->proyecto_id = $res['proyecto_id']+0;
$proy->proyecto_codigo=$res['proyecto_codigo'];
$proy->proyecto_nombre=$res['proyecto_nombre'];
$proy->creado=$res['creado'];
$proy->creadopor=$res['creadopor'];
$proy->actualizado=$res['actualizado'];
$proy->actualizadopor=$res['actualizadopor'];
$proy->institucion_id=$res['institucion_id']+0;
$proy->tipoproyecto_id=$res['tipoproyecto_id']+0;
$proy->organizacionint_id=$res['organizacionint_id']+0;
//////////

return$proy;
}

/**
* Leer toda la tabla
*
*/
public function getAllProyectos()
{
$res=$this->proyectos->fetchAll()->toArray();
return$res;//$aarea;
}
18


/**
* Get items from the database in specific increments
* @paramint $startIndex
* @paramint $numItems
*/
public function getProyectosPaged($startIndex, $numItems)
{
$tabla = "gpi_proyectos.proyectos";
$consulta="select * from $tabla limit $numItems offset $startIndex";
$res=$this->proyectos->getAdapter()->fetchAll($consulta);
return$res;//$aarea;
}

/**
* Inserta un Item en la Tabla de Areas
* @paramproyectos_vo $proy
* @returnint
*/
publicfunctioncreateProyecto($proy)
{

///$adata=(array)$fin_vo; Transformar el objeto, en array
$tabla = "gpi_proyectos.proyectos";//$this->getNombreTabla();
$data = array(
'proyecto_id' => $proy->proyecto_id,
'proyecto_codigo' => $proy->proyecto_codigo,
'proyecto_nombre' => $proy->proyecto_nombre,
'creado' => $proy->creado,
'creadopor' => $proy->creadopor,
'actualizado' => $proy->actualizado,
'actualizadopor' => $proy->actualizadopor,
'institucion_id' => $proy->institucion_id,
'tipoproyecto_id' => $proy->tipoproyecto_id,
'organizacionint_id'=> $proy->organizacionint_id);
$this->proyectos->insert($data);
return$this->proyectos->getAdapter()->lastInsertId($tabla,'proyecto_id');
}

/**
* Modifica un registro del area
* El codigopincipal no se modifica
* @paramproyectos_vo $proy
* @returnproyectos_vo
*/
publicfunctionupdateProyecto($proy)
{
$tabla = "gpi_proyectos.proyectos";//$this->getNombreTabla();
$data = array(
'proyecto_codigo' => $proy->proyecto_codigo,
'proyecto_nombre' => $proy->proyecto_nombre,
'creado' => $proy->creado,
'creadopor' => $proy->creadopor,
'actualizado' => $proy->actualizado,
'actualizadopor' => $proy->actualizadopor,
'institucion_id' => $proy->institucion_id,
'tipoproyecto_id' => $proy->tipoproyecto_id,
'organizacionint_id'=> $proy->organizacionint_id);

$this->proyectos->update($data,'proyecto_id='.$proy->proyecto_id );

19

return$this->getproyectosByID($proy->proyecto_id);
}

/**
* Elimina registro de una area
* @paramint $id
* @returnbool
*/
publicfunctiondeleteProyecto($id)
{
$rs=false;
$tabla = "gpi_proyectos.proyectos";//$this->getNombreTabla();
$afect=$this->proyectos->delete('proyecto_id='.$id);
if($afect!=0)
$rs=true;
return$rs;
}
/**
* Get the total number of records in the database
* @returnint
*/
public function countProyectos()
{
//$tabla = $this->getNombreTabla();
$tabla='gpi_proyectos.proyectos';
$count=$this->proyectos->getAdapter()->fetchOne('SELECT COUNT(*) FROM
'.$tabla);
return$count=(int)$count;
}


}

14. Crear los servicios AS desde Flash Builder
El siguiente paso es crear los servicios homlogos para el frontal en Flash Builder que nos permitir conectarnos a los
servicios de PHP. Seleccionar el proyecto Flex usamos opcion Data->Connectto Data/Service.


20

En el cuadro de dilogo que aparece seleccionamos "phpbyZend", luego presionamos "Next", luego seleccionamos
usando el boton "Browse" el servicio php creado anteriormente que se encuentra en la carpeta services de nuestro
proyecto php.



Damos click en Finish. Hecho esto automticamente Flash Builder crear un enlace hacia los servicios PHP, adems se
crean tambin los servicios homlogos ubicados en las nuevas carpetas que se crearan en el proyecto Flex, dentro de
src llamadas "services" y "valueObjects".

Si echamos un vistazo al servicio vemos que la tipificacin de datos ya se crea automticamente, slo hay dos mtodos
cuyo valor devuelto es tipo objeto (circulo gris), es porque el servicio en php devuelve un objeto, y todos los tipos de
datos conocidos que se devuelva. Pero como AS no maneja objetos (aclarar esto) en la serializacin sino arrays los
podemos tipificar manualmente, de la siguiente manera:
21

Damos click derecho sobre el mtodo con el crculo negro, que en mi caso es getAllProyectos(), y seleccionamos la
opcin "Configure ReturnType". En el cuadro de Dilogo que aparece seleccionamos la opcin "Use anexisting data
type", y en el combo seleccionamos el tipo de dato "Proyectos_vo[]" que corresponde a la clase creada inicialmente en
php, los corchetes indican que es un es de tipo array de objetos. Presionamos Finish, y ya le habremos asignado al
mtodo el tipo de datos que devuelve. Lo mismo hacemos con el otro mtodo.
Lo anterior funciona si en la carpeta servicios de PHP creamos una clase mapeadora (VO) que contiene atributos que se
corresponden a los campos de la tabla ; y dentro del servicio PHP lo instanciamos agregndole los datos de cada campo
obtenidos en la consulta y luego devolvemos esa instancia, solo as en Flash builder nos reconocer como un nuevo tipo
de datos.
Flash builder nos facilita las cosas porque en el lado del FRONT puede generar el VO automticamente tomando datos
desde un servicio de php que nos devuelva el registro completo. como desde zend lo hace fetchall(), a partir de ese
resultado Flash builder puede ayudarnos a genera el tipo de dato VO con la opcion Auto-detect.
Como en la opcin anterior en lugar de usar un "tipo existente", seleccionamos "Auto -detect ", luego Next, aqu Flash
Builder ejecutar el servicio y de acuerdo a los datos devueltos detectar automticamente los tipos de datos que el
objeto devuelve, y luego le podemos asignar un nombre cualquiera a nuestro nuevo tipo de dato. Si la consulta devuelve
varios objetos(del nuevo tipo), el tipo de dato puede ser un array de ese nuevo tipo de datos. Hecho esto se crean
automticamente los VO en el Flex en su carpera "ValueObjects" de src.
Este VO ser pasado como parmetro en cualquier servicio PHP que lo necesite, y dentro del php este objeto deber
transformarse en un array.
Miremos los servicios , ya no tenemos crculos grises:


Luego de generar los servicios NO OLVIDEMOS ir a la carpeta public de PHP, buscar el archivo index.php, editarlo para
comentar la ltima lnea, porque no lo necesitamos, solo necesitamos el bootstrap. Luego tenemos que incluir en la
primera lnea dentro del gateway.php el archivo index.php. Esto es MUY IMPORTANTE, caso contrario nos dar
problemas de que no encuentra la clase....etc. (Anteriormente, tena la idea errnea de que deba copiarse el
bootstrape.php, pero no es as. El contenido del index.php es el mismo).


El contenido del bootstrap o del index de la carpeta public es:
<?php

// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
22


// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') :
'production'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));

/** Zend_Application */
require_once'Zend/Application.php';

// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH .'/configs/application.ini'
);
$application->bootstrap();

y hasta aqui esta es la estructura del proyecto php

Finalmente podemos probar que todos los mtodos funcionen, dando click derecho sobre cada uno y seleccionar
"TestOperation", en mi caso selecciono el mtodo "countProyectos" que me dar los registros que tiene la tabla.

23

15.- Redisear el Datagrid. Antes de ejecutar nuestra aplicacin el cual consiste en cargar un datagrid con
datos desde una tabla de postgres es necesario que rediseemos el datagrid. Primero vamos a eliminar el anterior y
crearlo nuevamente en modo diseo, lo concatenamos con un servicio en nuestro caso con getAllProyectos() que nos
devuelve toda la tabla. Lo hacemos dando click en el icono en forma de cadena:

Al mensaje le damos OK y nos aparecer el cuadro de dialogo donde seleccionaremos el mtodo ya mencionado:

Tambin le daamos OK. D esta fora nos generar la tabla con los campos respectivos que necesitamos.
Y como lo que necesitamos es slo la estructura de la tabla, y nada ms, ya no necesito todo el cdigo que se
autogener como los callResponder con su respectiva funcin de llenado del datagrid y dems cdigo .
Este es el cdigo con lo autogenerado:
<?xml version="1.0" encoding="utf-8"?>
<s:Groupxmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:proyectoserv="services.proyectoserv.*"
width="400" height="300">
<fx:Script>
<![CDATA[
importmx.controls.Alert;
importmx.events.FlexEvent;


protectedfunctiondataGrid_creationCompleteHandler(event:FlexEvent):void
{
getAllProyectosResult.token = proyectoServ.getAllProyectos();
}

]]>
</fx:Script>
<fx:Declarations>
<s:CallResponder id="getAllProyectosResult"/>
<proyectoserv:ProyectoServ id="proyectoServ"
fault="Alert.show(event.fault.faultString + '\n' +
event.fault.faultDetail)"
24

showBusyCursor="true"/>

<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Button x="16" y="1" label="CargarDatos" click="dispatchEvent(new Event('CARGA_DATA'))"/>
<s:DataGrid id="dataGrid" x="60" y="195"
creationComplete="dataGrid_creationCompleteHandler(event)" requestedRowCount="4">
<s:columns>
<s:ArrayList>
<s:GridColumndataField="proyecto_id" headerText="proyecto_id"></s:GridColumn>
<s:GridColumndataField="proyecto_codigo"
headerText="proyecto_codigo"></s:GridColumn>
<s:GridColumndataField="proyecto_nombre"
headerText="proyecto_nombre"></s:GridColumn>
<s:GridColumndataField="creado" headerText="creado"></s:GridColumn>
<s:GridColumndataField="creadopor" headerText="creadopor"></s:GridColumn>
<s:GridColumndataField="actualizado" headerText="actualizado"></s:GridColumn>
<s:GridColumndataField="actualizadopor"
headerText="actualizadopor"></s:GridColumn>
<s:GridColumndataField="institucion_id"
headerText="institucion_id"></s:GridColumn>
<s:GridColumndataField="tipoproyecto_id"
headerText="tipoproyecto_id"></s:GridColumn>
<s:GridColumndataField="organizacionint_id"
headerText="organizacionint_id"></s:GridColumn>
</s:ArrayList>
</s:columns>
<s:typicalItem>
<fx:Object actualizado="actualizado1" actualizadopor="actualizadopor1" creado="creado1"
creadopor="creadopor1" institucion_id="institucion_id1"
organizacionint_id="organizacionint_id1" proyecto_codigo="proyecto_codigo1"
proyecto_id="proyecto_id1" proyecto_nombre="proyecto_nombre1"
tipoproyecto_id="tipoproyecto_id1"></fx:Object>
</s:typicalItem>
<s:AsyncListView list="{getAllProyectosResult.lastResult}"/>
</s:DataGrid>
</s:Group>


Y Debe quedar as:
<?xml version="1.0" encoding="utf-8"?>
<s:Groupxmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:proyectoserv="services.proyectoserv.*"
width="400" height="300">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Button x="16" y="1" label="CargarDatos" click="dispatchEvent(new Event('CARGA_DATA'))"/>
<s:DataGrid x="13" y="29" width="293" height="133" id="GridGen">
<s:columns>
<s:ArrayList>
<s:GridColumndataField="proyecto_id" headerText="proyecto_id"></s:GridColumn>
<s:GridColumndataField="proyecto_codigo"
headerText="proyecto_codigo"></s:GridColumn>
<s:GridColumndataField="proyecto_nombre"
headerText="proyecto_nombre"></s:GridColumn>
<s:GridColumndataField="creado" headerText="creado"></s:GridColumn>
<s:GridColumndataField="creadopor" headerText="creadopor"></s:GridColumn>
<s:GridColumndataField="actualizado" headerText="actualizado"></s:GridColumn>
<s:GridColumndataField="actualizadopor"
headerText="actualizadopor"></s:GridColumn>
<s:GridColumndataField="institucion_id"
headerText="institucion_id"></s:GridColumn>
<s:GridColumndataField="tipoproyecto_id"
headerText="tipoproyecto_id"></s:GridColumn>
<s:GridColumndataField="organizacionint_id"
headerText="organizacionint_id"></s:GridColumn>
</s:ArrayList>
</s:columns>
25

<s:typicalItem>
<fx:Object actualizado="actualizado1" actualizadopor="actualizadopor1" creado="creado1"
creadopor="creadopor1" institucion_id="institucion_id1"
organizacionint_id="organizacionint_id1" proyecto_codigo="proyecto_codigo1"
proyecto_id="proyecto_id1" proyecto_nombre="proyecto_nombre1"
tipoproyecto_id="tipoproyecto_id1"></fx:Object>
</s:typicalItem>
</s:DataGrid>
</s:Group>

Si esto es mucho lio tambin lo que podemos hacer es no borrar el grid de inicio de este manual y en su defecto
modificarlo con los nombres de los campos y nmero de columnas de la tabla a recuperar.
Ahora s ha probar, y nos dar el siguiente resultado:


Recomendacin y en Resumen
Luego de haber experimentado, lo ms conveniente es seguir este orden:
1. Generar las Tablas en la Base de Datos. Para empezar con una tabla con 3 campos y 2 registros
2. Generar los Proyectos Flex y PHP (Con Flash Builder)
3. Con Zend Tools desde Flash Builder crear el proyecto zend sobre el proyecto PHP anteriormente creado,
configurar el adaptador de BD, generar los modelos de las tablas.
4. En Flash Builder crear los servicios PHP (tal como se indic), con un servicio que recupere todos los datos de la
tabla est bien.
5. Realizar la conexin con los servicios PHP, lo que hace que Flash Builder genere al mismo tiempo los servicios en
AS3.
6. Probar que funcionen los servicios.
7. Generar la estructura de RobotLegs.
- Crear la vista y sus controles , generando los eventos
- Crear el mediador para la vista, que captura el evento y genera otro evento
- Crear el Contexto (Junto al xml principal), en donde relacionamos a los actores
- Crear los modelos
- Crear la clase con los Eventos
- Crear los comandos
- Ir al Contexto y relacionar el evento generado en el mediador con el comando creado
- Ir al mediador y relacionar el evento generado al actualizar el modelo para actualizar la vista.
26

TIPS a tomar en cuenta
Durante mi aprendizaje me encontr con errores que me detuvieron por mucho tiempo por no conocer ciertos detalles
que dejamos pasar y a veces son bsicos pero se dan, aqu algunos de ellos:
Campos NULOS
La forma de manejar los campos NULL es diferente en muchos lenguajes y en las mismas BD. En AS los campos nulos se
declaran con null, en PHP como NULL al igual que en Postgres. Es importante saber que al pasar de AS un campo como
null el php lo transforma como 0 (cero). Este tema me tuvo largo rato dando vueltas, hasta que lo detect y tuve que
hacer en php que cuando llegue cero a mi campo le asigno NULL. Y eso fue todo.
Error Obtenido: select the local resource that matches the following server path
.Seguramente algo cambie en la configuracin de zend, que de un momento a otro apareci este error. Aunque luego de
que la ltima vez que cerre el Flash Builder ste no respondi y tuve que cerrarlo a la fuerza. Seguramente all algo no
termin de hacer y crashhh. Este error lo podemos ver cuando ejecutamos en modo debuger, porque si lo hacemos
normalmente slo se obtiene un mensaje de que hay errores en el proyecto, aunque aparentemente no obtengo ningn
aviso visual en el cdigo porque todo estaba bien.
En principio no hay que preocuparse mucho, porque si se ejecuta bien en modo normal

Para recordar:
En el archivo de configuracin php.ini se establecen todas las caractersticas que se van a usar de Zend, de esta forma
usaremos las librerias de Zend desde un solo lugar, y no tendremos que hacer una copia para cada proyecto.
El directorio Web en mi caso ser "C:\Program Files (x86)\Zend\Apache2/htdocs"
El directorio Public de cada proyecto es el punto de entrada a la aplicacin desde el navegador, mediante el archivo
index.php, o el archivo bootstrap.php (ambos tienen el mismo contenido). Aqu se carga la configuracin inicial
estableciendo el path al directorio "myproyecto/application", en donde se carga el archivo
"myproyecto/application/configs/Application.ini", este archivo contiene los datos iniciales para acceso a la base de
datos.
Nota: Si tenemos activado modo_ rewrite en Apache no es necesario el index.php.
Luego en el archivo index.php se crea el objeto de la aplicacin con la configuracin cargada y luego se crea el bootstrap
y se ejecuta la aplicacin:
// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap()
27

->run();

Para un proyecto Zend, la carpeta Application es en donde est todo el cdigo de nuestra aplicacin, pero en nuestro
caso al usar Flex como Front, esta carpeta sirve para guardar el archivo de configuracin de acceso a la BD (entre otras)
en la carpeta configs, y los modelos de nuestras tablas en la carpeta models. No usaremos el bootstrap.php de esta
carpeta.


Para usar el archivo .htacces se debe activar el modo re_write en el archivo de configuracin del apache: busca la linea
donde dice:
#LoadModule rewrite_module modules/mod_rewrite.so

quitale el: #

Cuando realizamos un proyecto Flex con Flash Builder y poder acceder a los servicios php usando Zend, se crean los
archivos de configuracin : amf_config.php y gateway.php que se hallan en la carpeta public.
En realidad se ha comprobado que gateway.php se ejecuta en primer lugar por eso se coloca el archivo index.php o el
bootstrap.php dentro de gateway.php.
Si ya se va a subir la aplicacin a un servidor, es recomendable que la configuracin de PHP services tome en cuenta esos
cambios y compilarlo para finalmente subirlo al servidor.

Se puede usar los mismos servicios php en diferentes proyectos Flex.

Usando Datamanagement
Flash Builder nos da la posibilidad de facilitar el manejo de tablas automatizando tareas en una tabla como Crear,
Modificar, Actualizar registros.
Lo que hace es....


28

Aplicacin Modular
El proyecto se ha iniciado con una visin modular, intentando en lo posible minimizar la carga durante las llamadas.
Como en el proyecto tenemos Varios Subsistemas, y cada subsistema tendr mdulos que podrn ser usados por
cualquier otro susbsistema.
En ese sentido organizamos nuestros proyectos de Flash Builder, de tal forma que cada proyecto equivale a un
Subsistema. De acuerdo a como vemos en el siguiente grfico:

Aqu tambin est el Men principal de la Suite general llamado GpiGestion, el cual servir de entrada a los dems
subsistemas, que de acuerdo al grfico seran: CoopInternacional, GpiPlanificacion.
Se trabaja con un solo BackEnd, que lo hemos llamado GpiGestPhp, Todos los subsistemas usarn los servicios que se
encuentran en este proyecto php (ubicado en nuestro root).
Dentro de cada proyecto se organiza de la forma en cmo nos suguiere robotlegs para as usar el patrn MVC. Pero
adems en esta estructura crearemos una nueva carpeta (NO Package) en donde se guardan los modulos de cada
subsistema.
Estos mdulos son creados desde el men File - New - MXML MODULE, estos archivos al compilar generarn un swf
independiente.

29

En este mdulo colocaremos el contexto y la vista, es decir que ya no usaremos el mxml principal, pues ste ser usado
nicamente para contener el men principal de cada proyecto o subsistema que llamar a los mdulos. El siguiente
grfico nos muestra un panorama general de la estructura.

Vemos que El proyecto o subsistema se llama GpiPlanificacin, por lo tanto el mxml principal se llama
GpiPlanificacion.mxml (que es de tipo Application), en ste estar el men principal.
Tambin Tenemos la carpeta ModulosPlanificacion, aqu vemos el archivo NivelPlanificacion.mxml (de tipo Module) que
es el que realiza la tarea especfica puede ser llamada desde el men de este subsistema o de cualquier otro. En este
archivo se har la llamada al contexto, as como a la vista que se encuentra en views (NivelPlanificacionView.mxml).
Los eventos, comandos, modelos podrn ser usados en cualquiera de los mdulos que se vayan creando.
Identificacin de los Servicios del Sistema
Los servicios se refiere a la funcionalidad que va a entregar el sistema a desarrollar; por lo tanto el identificarlos requiere
del conocimiento de lo que se va a hacer, los procesos que se llevan a cabo para cumplir con la funcionalidad, y en forma
ms amplia conocer los procesos empresariales, que deben estar ya establecidos en los manuales de procesos de la
institucin. Caso contrario la tarea se volver ms pesada porque debemos establecer esos procesos con la aprobacin
de la planta directiva.
Encontrados los servicios procedemos a identificar los servicios concretos que pueden reflejarse como en nuestro caso
en los servicios que permiten hacer operaciones en la tablas como adicionar, modificar, eliminar, etc. (corresponden a
los archivos php).

Procesos en notacin BPM.
Aqu va el modelamiento de todos los procesos levantados en notacin BPMN
30

Modelado de la Base de Datos
En base a los servicios detectados y analizando los procesos nos dar una orientacin para modelar las tablas, sus
campos y relaciones.
Modelado de casos de uso (UML)
Con el fin de conocer cmo interactuar el usuario con las diferentes tablas, sea modificando, borrando, etc. Indicando
tambin los prerrequisitos (por ej si tiene clave fornea, debe existir datos previos en la tabla fornea), se diagrama los
casos de uso. Esto servir para que si otro DBA se hace cargo del modelado, pueda entender fcilmente las relaciones.
Diseo de la interfaz de usuario
Maquetacin.
En la maquetacin nos ayudar mucho usar los layout que son controles contenedores con sus propias
caractersticas.Nos ayudar mucho los Navigators como el viewstack
Definiremos las reas de la que se compone nuestra aplicacin:
- rea de Identificacion
- Barra de Ttulo
- rea de controles
- rea de trabajo
Como layouts usaremos
Panel
Titlewindow
Diseo de la Aplicacin Principal
Nuestra aplicacin principal estar compuesta por un TitleWindow, la Barra de Controles y un ModuleLoader (Area de
trabajo)
Para la Barra de controles usaremos un TabBar con un viewstack.
En modo de diseo crearemos el viewstack arrastrndolo desde el rea de controles, luego le asignamos un id que nos
recuerde los contenidos del viewstack. En mi caso lo que nos mostrar es barras de botones que se cargarn segn el
tab clicado. Luego de darle un id, aadimos un TabBar, ahora le asignamos o enlazamos el control en base al cual se
generan las pestaas, es decir en este caso le asignamos el id del viewstack, para ello en la parte de propiedades del
Tabbar colocamos el id del viewstack en la propiedad dataprovider.
Dentro de cada viewstack colocaremos la barra de botones que est compuesta por un ApplicationControlBar, que
contiene un ButtonBar.
31


Ahora podemos ir aadiendo dentro del viewstack los NavigatorContent cuyo id ser el que aparezca o que se relaciona
con una pestaa.
ModuleLoader
Luego de la barra de controles, colocaremos el control ModuleLoader, que es donde se cargarn los mdulos.

Esta es la apariencia final de la aplicacin principal GPI PLANIFICACION.
Nota. Para evitar que en cada item del viewstack se repita un ApplicationControlBar, podremos usar a este ltimo como
contenedor del viewstack. Quedando as:
<s:TitleWindow x="1" top="33" bottom="0" width="100%" title="GPI PLANIFICACION">
<mx:ApplicationControlBar id="InicioBar" x="6" y="37" width="99%" height="64"
cornerRadius="0" dock="false" fillColors="[#85b0ce,#f1f2f3]"
fillAlphas="[#85b0ce,#f1f2f3]" focusColor="#B6B778" >

<mx:ViewStack id="PlanifBarraVStack" x="6" y="36" width="776" height="50">
<s:NavigatorContent width="100%" height="100%" label="Planes">
<s:ButtonBar x="0" y="0" height="100%"
32


change="SelModulosPlanif(event,aModulosPlan,CargaPlanif)"
dataProvider="{aMenuPlan}" />
</s:NavigatorContent>

<s:NavigatorContent width="100%" height="100%" label="Informacin Base">
<s:ButtonBar x="0" y="0" height="100%"

change="SelModulosPlanif(event,aModulosInfoBase,CargaPlanif)"
dataProvider="{aMenuInfoBase}"/>
</s:NavigatorContent>
</mx:ViewStack>
</mx:ApplicationControlBar>

<s:TabBar id="InicioTabBar" x="6" y="13" dataProvider="{PlanifBarraVStack}" />

<s:ModuleLoader id="CargaPlanif" x="10" y="120" width="100%" height="100%">
</s:ModuleLoader>
<mx:ProgressBar id="BarraAvance" x="342" y="227" visible="false" />

</s:TitleWindow>

Validadores
Para validar los campos de nuestros formularios usaremos los validadores predifinidos que nos ofrece Flex, y que
pueden ser aplicados a campos numricos, strings, fechas.
Para ello primero debemos declarar o inicializar la validacin para cada campo en el rea <fx:Declarations>, all
decidimos qu tipo de validador usar (NumberValidator, StringValidator) dndole un id a cada validador y luego en sus
propiedades decidimos que tipo de validacin aplicar, por ejemplo si es string podemos decir que el campo no est vacio
o que acepte un determinado nmero de caracteres, si es nmero podemos decir si debe ser mayor o menor a un
nmero, eso lo decidimos colocando en sus respectivas propiedades que debemos conocer; veamos el ejemplo:
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<!-- Define the validators. -->

<s:NumberValidator id="VNiveles"
source="{CbNiveles}"
property="selectedIndex" minValue="0" lessThanMinError="Debe
Seleccionar un Nivel" />
<s:NumberValidator id="VInstit"
source ="{CbInstit}"
property="selectedIndex" minValue="0" lessThanMinError="Debe
seleccionar una Institucin"/>

<mx:StringValidator id="VVision"
source ="{InVision}"
property="text" required="true" requiredFieldError="El campo no
debe estar vaco"/>

<mx:StringValidator id="VDesde"
source ="{DateDesde}"
property="text" required="true" requiredFieldError="El campo no
debe estar vaco"/>

</fx:Declarations>
Una Vez declarados los validadores podemos decidir como ejecutarlos, por ejemplo al
clicar un botn los ejecutaremos en una funcin:
33

private var vResult:ValidationResultEvent;
private function Validar():void {
vResult = VNiveles.validate();
if (vResult.type==ValidationResultEvent.INVALID)
return;

vResult = VInstit.validate();
if (vResult.type==ValidationResultEvent.INVALID)
return;

vResult = VVision.validate();
if (vResult.type==ValidationResultEvent.INVALID)
return;


vResult = VPlan.validate();
if (vResult.type==ValidationResultEvent.INVALID)
return;

vResult = VDesde.validate();
if (vResult.type==ValidationResultEvent.INVALID)
return;

vResult = VHasta.validate();
if (vResult.type==ValidationResultEvent.INVALID)
return;

}
Donde id es el identificador propio del validador, source es el identificador del control
(combo, input, datefield ) al que se aplica la validacin, property: se refiere a la
propiedad en la que el control graba el dato, por ejemplo si es combo ser:
selectedindex, si es input la propiedad es text.
Tambin podemos colocar a todos los id de los validadores en un array para que se evalen
todos en un solo click del botn usando Validator y su mtodo validateAll. Yo uso este
mtodo pues permite que el usuario visualice en una sola accin que campos necesita
modificar, y cuando todos estn validados despacho el evento de grabar. Previamente en el
creationComplete se inicializa el array con los validadores
private var myValidators:Array;


protected function initValidTodo(event:FlexEvent):void
{
// TODO Auto-generated method stub
myValidators=[VNiveles,VInstit,VVision,VPlan, VPeriodos,VDesde,VHasta];
}

protected function ValidarTodo(event:MouseEvent):void
{
// TODO Auto-generated method stub
if(Validator.validateAll(myValidators).length==0)
dispatchEvent(new Event('GRABA_DATOSGEN_PLAN',true));
}

34

Servicios PHP USADOS
FinesServ.php
GetAllFines() retorna un array de registros
GetAllFinesFiltro($institucion,$orginterna,$tipoplan)
GetAllFinesHijos($afin) afin contiene id del padre y tipo de fin
GetFinById($id)
DeleteFin($id)
NewFin($fin_vo)
UpdateFin($fin_vo)

PlanEstrategiasServTr.php
NewPlanEstra($aPlanEstrategias)
GetPlanEstraById($afin) Esta funcin usa GetAllFinesHijos($afin) de FinesServ.php
UpdatePlanEstra($aPlanEstra)
PlanInfoGServTr.php
NewPlanInfoG($aPlaninfoG)
GetPlanInfoGById($id) .- Usa los servicios FinesSer, FinesEnlacesServ, PeriodostiempoServ, y PlanificacinNivelesServ
UpdatePlan($aPlanInfoG)


ItemRender e ItemEditor en Spark DataGrids
El Itemrender permite personalizar la presentacin de una columna en especial. Podemos darle colores, fuentes y tamao
especiales, asignarle un control especfico para la visualizacin de la columna con datos.
El ItemEditor permite personalizar la edicin de una celda, por lo que es visible slo en el momento de la edicin. As podemos
cambiar la edicin por un dropdownlist, un spinner, checkbox, o cualquier otro control deseado, para modificar el valor de la celda.



35

Problemas encontrados
Error #1065: Variable ProgProyView is not defined.
Al hacer un Inject en el mediador de la vista, se obtuvo ese error, esto sucede cuando se trabaja con mdulos, y para solucionarlo se
carg el contexto desde la aplicacin principal y no desde el modulo.

Pasar Variables de la Aplicacin a un PopUp
A veces es necesario pasar datos desde la aplicacin que llama al popup. Para solucionar esto lo que he hecho es crear variables
publicas en la vista del PopUp. Luego al momento de crear el popup desde el mediador ya puedo acceder a sus variables y en donde
puedo hacer la asignacin de las variables que estn en la vista principal, ya que en el mediador he realizado un inject de dicha vista
Algo as:
En el mediador se inyecta la vista principal que es la que llama al pop
[Inject]public var viewProg:ProgProyView;
En algn lado del mediador se crea el pop
//Crear el PopUp
var popup:MetodosTiposPopUp = new MetodosTiposPopUp;
PopUpManager.addPopUp( popup,contextViews,true ); // contextView is defined in Command
mediatorMap.createMediator( popup );
//Ya Se puede acceder a las variables publicas del popup
popup.institucion=
viewProg.cbInst.dataProvider[viewProg.cbInst.selectedIndex].institucion_id;
popup.dependencia=
viewProg.cbDepend.dataProvider[viewProg.cbDepend.selectedIndex].organizacionint_id;
popup.title = "Estructura de Programas para:" +
viewProg.cbInst.dataProvider[viewProg.cbInst.selectedIndex].institucion_nombre;

MetodosTiposPopUp(PopUpManager.centerPopUp(popup));
Creado el PopUp podemos lanzar un evento cualquiera, que escuchar en todos los mediadores que se haya mapeado en el
contexto, y de esta forma podemos usar ese evento por ejemplo para que al abrirse el popup se carge con datos iniciales de una
tabla. En el mediador del popup se le adiciona un escuchador del contexto, para que escuche el evento lanzado aqu.


36

COMPONENTES MX Y SPARK

<mx:Component>
Esta etiqueta no acepta desde flex 4 por lo tanto se lo debe reemplazar con : <fx:Component>
<mx:DateFormatter>
Antes se usaba <mx:DateFormatter> fuera de declarations, Ahora se debe usar <s:DateTimeFormatter> dentro de Declarations en
flex 4 hacia adelante
Ej:
Antes:
<mx:DateFormatter> id="dateFormatter" formatString="JJ:NN"/>
Ahora:
<fx:Declarations>
<s:DateTimeFormatter id="DateDisplay4" dateTimePattern="yyyy.MMMM.dd HH:mm:ss" />
<s:DateTimeFormatter id="dateFormatter" dateTimePattern="JJ:NN"/>
</fx:Declarations>

"3608: 'application' has been deprecated since 4.0. Please use 'FlexGlobals.topLevelApplication'."

Just replace every "Application.application" reference in your project with "FlexGlobals.topLevelApplication". Remember to also
replace the "import mx.core.Application" with "import mx.core.FlexGlobals".

37

Trabajando con Aplicaciones y subaplicaciones usando SWFLoader

Comunicacin entre Aplicacin y Subaplicacion
La comunicacin entre estos modulos se realiza a travez de SystemManager

La comunicacin puede hacerse por eventos desde el hijo al padre, el hijo despacha un evento por ejemplo en el addToStage o
desde un botn.
dispatchEvent(new Event(desdehijo,true));
En tanto que en el padre se llama al hijo usando swfLoader en el evento complete:
CargaApli.content.addEventListener('desdehijo',mensaje);
public function mensaje(e:Event):void{
Alert.show("ya puedo hacer algo");
}
Pero an no puedo llegar a comunicar en la via opuesta desde el Padre hacia el hijo, que es lo que me interesa.
Para salvar este escollo, he decidido usar los sharedObject que son como las cokies del navegador. En donde el modulo padre
guardar informacin en este shared object ubicado en la mquina cliente, y el modulo hijo leer los datos desde este objeto.
Los sharedobjects guardan cualquier variable al disco. Esto me ha permitido cargar informacin que comparten todos los mdulos.
Para poder cargar con datos iniciales en los combos de una vista (con Robotlegs) he despachado un evento en el onRegister del
mediador el mismo que fue mapeado en el contexto para que ejecute un comando, y es este comando que lee el Sharedobject y
finalmente despacha un evento que es escuchado en el mediador, en donde se actualiza el combo con los datos.
En mediador (dentro del onRegister):
addContextListener('INSTITUCIONES_DESDE_FUERA',AsignaModeloInst);
dispatch(new Event('inicializado_up'));
En contexto (dentro del startUp):
commandMap.mapEvent("inicializado_up",CargarLogeoCom);
En comando
public var _recLogeo:SharedObject=SharedObject.getLocal('InfoTemp','/');
override public function execute():void{
var InstOut:Object=_recLogeo.data;
if(_recLogeo.data.usuario_id){
if(_recLogeo.data.instituciones.length!=0){
dispatch(new ResultEvent("INSTITUCIONES_DESDE_FUERA",true,true,InstOut));

}
}
}
38

Al usar los shared objects, se debe dar el permiso necesario al Flash Player para que pueda escribir en el disco. Esto se lo hace en
configuracin global del Flash Player:




Reportes con Stimulsoft
Stimulsoft tiene una interfaz grfica muy bien lograda, y la vamos a usar en nuestras aplicaciones.
Consta de dos mdulos: El diseador y el Visor.
Con el Diseador vamos a construir y personalizar los reportes en funcin de los datos a mostrar, para luego grabarlo como un
archivo mrt, en este archivo se graba las estructura del reporte.
El visor ser el que la mayora de usuarios utilizar para visualizar los datos con la estructura creada en el archivo mrt.
Antes de empezar se debe copiar los componentes swc tanto del visor como del diseador hacia la carpeta lib de nuestro proyecto.
Una de las formas que usa stimulsoft para crear los reportes es con los denominados Datasets. Esto nos permite armar el reporte
desde nuestro cdigo a partir de un datagrid.
1. Armar la tabla desde cdigo:
var table: DataTable = new DataTable("Customers");

var column: DataColumn = new DataColumn("Name", StorageType.StringType);
table.columns.add(column);
table.addNewRow().sett("Name", "Marcelo Jingo");
table.addNewRow().sett("Name", "Antonio Moreno");
table.addNewRow().sett("Name", "Elizabeth Brown");
var dataSet: DataSet = new DataSet("DataSetName");
dataSet.tables.add(table);
39

2. Tomar en cuenta el nombre de la tabla Customers y de las columnas en este caso Name, que sern usados para el diseo
del reporte.
3. Usar el diseador de reportes:
a. Crear un nuevo datasource en la pestaa dictionary, seleccionando from DataSet, DataTables.


b. Luego nos aparece el dilogo para armar nuestra tabla con las columnas. Name in Source es el Nombre para todo
el Origen de Datos el que va a contener varias tablas. Name= es el nombre de la Tabla. En nuestro caso hemos
puesto Customers tanto para origen de datos como para el nombre de tabla.


c. Usando el icono para adicionar columnas vamos creando las columnas necesarias, de acuerdo a lo que tengamos
en cdigo. Colocamos el nombre y el tipo de dato.
40


d. Ahora vamos a disear el encabezado, ttulos y datos, usando el icono Bands:


En el ancabezado podemos usar la herramienta Text
41



e. Agregamos la banda de datos con el respectivo icono, y seleccionamos el datasource que en este caso es
Customers

f. Aadimos las columnas arrastrando al DataBand

g. Grabamos el reporte con la extensin mrt y el nombre que se desee.
Si en este momento colocamos el preview, no obtendremos nada porque no hay datos. Los datos se colocan desde
el cdigo cuando ejecutemos la aplicacin, y lo llamamos tal como se indica en el inicio.
4. Compilamos nuestra aplicacin en donde llamamos a nuestro reporte.mrt creado y obtendremos el reporte
42

Das könnte Ihnen auch gefallen