Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

The following diagram shows how the ActionScript List component is composed.

Gliffy Diagram
sizeL
nameListComponent

...

The List contains:

  • A selection model which encapsulates a data provider as well knowledge about which item is selected (the item and the index).
  • A view bean bead that displays the container housing the list control.
  • A factory bean bead that can produce instances of item renderers as needed.
  • An item renderer to display each element of the list; created by the factory beanbead.
  • A mouse controller for the list as a whole that handles the selection for the list.
  • A mouse controller for item renderer to handle the hover and selected states.

These parts are specified by the List's style definition in the defaults.css file:

Code Block

List
{
    IBeadModel: ClassReference("org.apache.flex.html.staticControls.beads.models.ArraySelectionModel");
    IBeadView:  ClassReference("org.apache.flex.html.staticControls.beads.ListView");       
    IBeadController: ClassReference("org.apache.flex.html.staticControls.beads.controllers.ListSingleSelectionMouseController");
    IBeadLayout: ClassReference("org.apache.flex.html.staticControls.beads.layouts.NonVirtualVerticalScrollingLayout.VerticalScrollingLayout");
    IDataGroup: ClassReference("org.apache.flex.html.supportClasses.DataGroup");
    IDataProviderItemRendererMapper: ClassReference("org.apache.flex.html.staticControls.beads.TextItemRendererFactoryForArrayDataDataItemRendererFactoryForArrayData");
    IItemRendererClassFactory: ClassReference("org.apache.flex.core.ItemRendererClassFactory");
    IItemRenderer: ClassReference("org.apache.flex.html.staticControls.supportClasses.StringItemRenderer");
}

...

Once the List component and all of the item renderers have been created, the interactive part comes into play. Each item renderer is also a component (strand and beads) and follows the same pattern as other FlexJS components. For the List, the IItemRenderer is specified in defaults.css as the StringItemRenderer class which has its own style definition, show here:

Code Block

StringItemRenderer
{
    IBeadController: ClassReference("org.apache.flex.html.staticControls.beads.controllers.ItemRendererMouseController");
    height: 16;
}

...

In the JavaScript, the bead classes are normal classes and events do not propagate from inner to outer class (the UI in JavaScript are HTML elements that the JavaScript classes are wrapping). This event flow makes it a little challenging to have an event dispatched on an item renderer be detected by the ListSingleSelectionMouseController which is listening for events coming through the view bead. In JavaScript, the event dispatched on the item renderer does not have an event chain parent so that detection is not possible.

Code Block

// from ItemRendererMouseController's handleMouseUp function
this.strand_.get_itemRendererParent().dispatchEvent(newEvent);

...

FlexJS comes with two pre-built itemRenderers and there will probably be more. The TextItemRenderer is used exclusively for arrays of strings and is used with the SimpleList control. The DataItemRenderer is useful for more complex data and that is the class your itemRenderers will mostly extend.

Code Block

public class ProductItemRenderer extends DataItemRenderer
{
    public function ProductItemRenderer()
    {
        super();
    }
		
    private var image:Image;
    private var title:Label;
    private var detail:Label;
}

...

Every itemRenderer should override the addedToParent() function and instantiate the components that make up the itemRenderer, as shown here:

Code Block

    override public function addedToParent():void
    {
        super.addedToParent();

        image = new Image();
        addElement(image);
			
        title = new Label();
        addElement(title);
			
        detail = new Label();
        addElement(detail);
    }

...

Once an itemRenderer has been created, it will be given the data to show by setting the itemRenderer's data property (virtualized lists, which are not yet developed in FlexJS, will recycle the itemRenderers and set the data property whenever they can used).

Code Block

    override public function set data(value:Object):void
    {
        super.data = value;
			
        image.source = data.image;
        title.text = data.title;
        detail.text = data.detail;
    }

...

Finally, the itemRenderer should respond to changes in its size. The base class, DataItemRenderer, intercepts the events that trigger this and automatically calls its adjustSize() function.

Code Block

    override public function adjustSize():void
    {
        var cy:Number = this.height/2;
			
        image.x = 4;
        image.y = cy - 16;
        image.width = 32;
        image.height = 32;
			
        title.x = 40;
        title.y = cy - 16;
			
        detail.x = 40;
        detail.y = cy;
			
        updateRenderer();
    }

...

Once you have created your itemRenderer you can add it a List control via a style definition (this one appears in the style block of MyInitialView):

Code Block

<fx:Style>
    @namespace basic "library://ns.apache.org/flexjs/basic";
    @namespace sample "products.*";

    sample|ProductItemRenderer {
        height: 40;
        IBeadController: ClassReference("org.apache.flex.html.staticControls.beads.controllers.ItemRendererMouseController");
    }
</fx:Style>

<basic:List id="productList"  x="20" y="400" width="200" height="150" className="productList">
    <basic:beads>
        <basic:ConstantBinding
                 sourceID="applicationModel"
                 sourcePropertyName="products"
                 destinationPropertyName="dataProvider" />
    </basic:beads>
</basic:List>

...