Handling Property Changes in a Spark Custom ItemRenderer

Written by

I recently got asked about how I store and retrieve data within a Spark DataGroup using a custom ItemRenderer, with a particular focus on how to monitor property changes. There are a few ways to achieve this, particularly when it comes to storing and retrieving data, here is one simple example using a CheckBox within a custom ItemRenderer and observing the total selected CheckBoxes.

Here I will detail the main snippets of functionality, download the actual source (links at bottom of the post) to get the full picture.

I tend to programme more in ActionScript as opposed to mxml, this is just my personal preference, however, lets do things a bit different and create a ValueObject using mxml and bind the selectedItems property to the selectedItems getter within custom List:

1
2
3
4
5
6
7
8
9
10
11
<fx:Declarations>
        <!-- demo dataprovider -->
        <fx:Array id="dp">
            <vo:Item itemName="Iron Man"/>
            <vo:Item itemName="Spiderman"/>
        </fx:Array>
        <!-- Custom vo -->
        <vo:CustomVO id="model">
            <vo:selectedItems>{itemList.selectedItems}</vo:selectedItems>
        </vo:CustomVO>
    </fx:Declarations>

In a custom List create a Bindable getter that the VO selectedItems property (see above) is bound to:

1
2
3
4
5
[Bindable(event="propertyChange")]
public function get selectedItems():Array
{
     return _items;
}

In the List create a handler for the dataChange Event:

1
2
3
4
protected function handleCreationComplete(event:FlexEvent):void
{
    list.addEventListener(FlexEvent.DATA_CHANGE, handleItemSelected);
}

Still within the List add a method to loop through the data provider to retrieve all the currently selected items. This will change the selectedItems total count and update bindings by dispatching a propertyChange Event:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
protected function handleItemSelected(event:FlexEvent):void
{
    setSelectedItems();
}

protected function setSelectedItems():void
{
    var i:int;
    var length:int=dataProvider.length;
    var item:Item;
    _items=[];
    for(i=0; i<length; i++)
    {
        item=dataProvider.getItemAt(i) as Item;
        if(item.itemSelected)
        {
            _items.push(item);
        }
    }
    dispatchEvent(new Event("propertyChange"));
}

Within the custom ItemRenderer a data Object is going to be assigned a custom VO named Item with the following properties:

1
2
public var itemName:String;
public var itemSelected:Boolean=false;

In the ItemRenderer assign a handler to the CheckBox change Event and update the data’s itemSelected property. If the itemSelected property has changed then dispatch a dataChange Event, this will ensure all the Bindings are kept in sync thus updating our custom VO in the main class.

1
2
3
4
5
6
protected function handleSelectionChange():void
{
    if(data.itemSelected==item_cb.selected) return;
    data.itemSelected=item_cb.selected;
    this.dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE, true));
}

This is a simple example as I stated above and there are many ways to achieve the final goal.

Hopefully this will help someone out there, and if you want to read more about Bindings then view my BindingUtils chain and DataBinding a Proxy to a Mediator posts.

View the example [wpfilebase tag=file id=1]

Comments