Comunidad de diseño web y desarrollo en internet online

Formas de uso de ItemRenderer y su comunicación en Flex

Cuando se empieza a desarrollar en Flex nos vamos dando cuenta que para crear un control personalizado hay muchas maneras y un problema clásico es la comunicación de estoy controles personalizados con el contenedor principal.

Aquí mostraré todas las formas que tenemos disponible para trabajar los ItemRenderer por MXML y como comunicar estos con su contenedor.

Elementos básicos de un ItemRenderer


Los archivos del siguiente ejemplo se los pueden descargar aquí. A continuación la explicación:

ValueObject

Código :

// Archivo: vo/PersonaVO.as
package vo
{
   [Bindable]
   public class PersonaVO
   {
      public var nombres:String;
      public var apellidos:String;
      public var nacimiento:Date;
      public var email:String;
      public var telefono:String;
      
      public function PersonaVO(nombres:String='', apellidos:String='')
      {
         this.nombres = nombres;
         this.apellidos = apellidos;
      }
   }
}

Evento Personalizado

Código :

// Archivo: events/PersonaEvent.as
package events
{
   import flash.events.Event;
   
   public class PersonaEvent extends Event
   {
      public static const REMOVE:String = 'personaRemove';
      
      public function PersonaEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
      {
         super(type, bubbles, cancelable);
      }
      
      override public function clone():Event
      {
         return new PersonaEvent(type, bubbles, cancelable);
      }
   }
}

ItemRenderer Personalizado

Código :

// Archivo: itemrenderer/PersonaListItemRenderer.as
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark" 
            xmlns:mx="library://ns.adobe.com/flex/mx" 
            autoDrawBackground="true" width="100%">
   
   <fx:Script>
      <![CDATA[
         import events.PersonaEvent;
         
         protected function btnEliminar_clickHandler(evt:MouseEvent):void
         {
            dispatchEvent( new PersonaEvent(PersonaEvent.REMOVE, true) );
         }
      ]]>
   </fx:Script>
   
   <s:Label
      text="{data.nombres} {data.apellidos}" 
      left="0" right="30" height="15" 
      verticalCenter="1"
   />
   <s:Button 
      id="btnEliminar" 
      label="X" 
      click="btnEliminar_clickHandler(event)"
      right="0" width="30" height="16"
      verticalCenter="0"
   />
   
</s:ItemRenderer>

Componente List Personalizado

Código :

// Archivo: components/PersonaList.as
package components
{
   import spark.components.List;
   
   [Event(name="personaRemove", type="events.PersonaEvent")]
   public class PersonaList extends List
   {
      public function PersonaList()
      {
         super();
      }
   }
}


Cómo usar ItemRenderer

1. List, ItemRenderer interno y uso de outerDocument

Cuando usamos un ItemRenderer interno podemos disponer de la propiedad outerDocument, ella hace referencia al contenedor principal del MXML.
Ejemplo:

Código :

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark" 
            xmlns:mx="library://ns.adobe.com/flex/mx"
            minWidth="600" minHeight="300"
            
            creationComplete="app_creationCompleteHandler(event)">
   
   <s:layout>
      <s:VerticalLayout
         gap="5"
         paddingLeft="10" paddingTop="10" 
         paddingRight="10" paddingBottom="10"
      />
   </s:layout>
   
   <fx:Script>
      <![CDATA[
         import mx.collections.ArrayList;
         import mx.events.FlexEvent;
         
         import vo.PersonaVO;

         [Bindable]
         private var alPersonas:ArrayList;
         
         protected function app_creationCompleteHandler(event:FlexEvent):void
         {
            // Creamos una Lista de Array con los datos
            alPersonas = new ArrayList();
            alPersonas.addItem( new PersonaVO('Raul','Sanchez') );
            alPersonas.addItem( new PersonaVO('Victor','Gonzales') );
            alPersonas.addItem( new PersonaVO('Cecilia','Casas') );
            alPersonas.addItem( new PersonaVO('Carlos','Rodriguez') );
            alPersonas.addItem( new PersonaVO('Luis','Cordoba') );
         }
         
         public function personaRemove(item:Object):void
         {
            alPersonas.removeItem( item );
         }

      ]]>
   </fx:Script>
   
   <s:List
      id="lstPersonas"
      dataProvider="{alPersonas}"
      width="155"
      >
      <s:itemRenderer>
         <fx:Component>
            <s:ItemRenderer width="100%">
               <fx:Script>
                  <![CDATA[
                     protected function btnEliminar_clickHandler(evt:MouseEvent):void
                     {
                        outerDocument.personaRemove( data );
                     }
                  ]]>
               </fx:Script>
               
               <s:Label
                  text="{data.nombres} {data.apellidos}" 
                  left="0" right="30" height="15" 
                  verticalCenter="1"
                  />
               <s:Button 
                  id="btnEliminar" 
                  label="X" 
                  click="btnEliminar_clickHandler(event)"
                  right="0" width="30" height="16"
                  verticalCenter="0"
                  />
            </s:ItemRenderer>
         </fx:Component>
      </s:itemRenderer>
   </s:List>   
   
</s:Application>

Aquí se uso outerDocument para comunicarse con el método publico "personaRemove".

2. List, ItemRenderer interno y uso de evento personalizado

Usando el ejemplo anterior agregaremos a la función app_creationCompleteHandler:

Código :

lstPersonas.addEventListener(PersonaEvent.REMOVE, lstPersonas_personaRemoveHandler);

Una función para escuchar el evento personalizado:

Código :

protected function lstPersonas_personaRemoveHandler(event:PersonaEvent):void
{
   var persona:PersonaVO = event.target.data as PersonaVO;
   personaRemove( persona );
}

Y reemplazamos la línea del outerDocument para disparar el evento personalizado.

Código :

// El segundo parámetro es importante para que se logré escuchar el evento.
dispatchEvent( new PersonaEvent(PersonaEvent.REMOVE, true) );


3. List, ItemRenderer externo y uso de evento personalizado


Usando el ejemplo anterior, el List ahora es:

Código :

<s:List
   id="lstPersonas" 
   itemRenderer="itemrenderer.PersonaListItemRenderer"
   dataProvider="{alPersonas}"
   width="155"
/>

Si se fijan en el archivo itemrenderer/PersonaListItemRenderer.as (ver al inicio), verán que es igual del del anterior ejemplo y se dispara el evento.

4. List personalizado (se agrego metadata Event), ItemRenderer externo y uso de evento personalizado


Usando el ejemplo anterior, el List ahora es:

Código :

<components:PersonaList
   id="lstPersonas" 
   itemRenderer="itemrenderer.PersonaListItemRenderer"
   dataProvider="{alPersonas}"
   width="155"
   personaRemove="lstPersonas_personaRemoveHandler(event)"
/>

La ventaja en esta última es el uso del Metadata Event en la clase extendida components/PersonaList.as .

Código :

[Event(name="personaRemove", type="events.PersonaEvent")]
Gracias a eso podemos escribir directamente el evento en el MXML:

Código :

personaRemove="lstPersonas_personaRemoveHandler(event)"


Son varios archivos los que he mostrado aquí pero necesarios para la comprensión y comunicación de los ItemRenderer.

Archivos del ejemplo: descargar.

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate