1
votes

I need to display DropDownLists in a column of a DataGrid in my Flex application. Here is what I am doing:

First, I have a item renderer function that creates a custom item renderer, and passes it a property that is an IList that will be used as the dataProvider of the dropDownList:

private function rendererFunction(item:Object):ClassFactory {       
            var itemRenderer:ClassFactory = new ClassFactory(AudActionDropDownIR);
            itemRenderer.properties = {AudActionData: AudActionData};
            return itemRenderer;
        }

This is the code for the custom item renderer class:

<fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.collections.IList;
            [Bindable]
            public var TheData:ArrayCollection = new ArrayCollection();
            public var AudActionData:IList;

            public function init():void
            {
                TheData = new ArrayCollection(AudActionData.toArray());
                TheData.filterFunction = filterTheData;
                TheData.refresh();
            }

            private function filterTheData(item:Object):Boolean {
                return item.AUD_STEP_TYPE_ID == data.AUD_STEP_TYPE_ID;
            }
        ]]>
    </fx:Script>
<s:DropDownList id="theList"
                labelField="AUD_ACTION_DESCR" 
                requireSelection="true" 
                selectedIndex="0"
                dataProvider="{TheData}"
                width="100%"/>

The IList that is passed to the renderer (AudActionData) is converted in to a filtered ArrayCollection that will be used as the dataProvider for the dropdownlist.

I am having a couple of issues with this.

First, how can I call the init function when the renderer is created? Second, when I set the column's itemRendererFunction="rendererFunction", the app will not launch, a white screen comes up. But when I set itemRenderer="components.AudActionDropDownIR", the app will launch, but of course there is no data in the dropdown list.

Any ideas? Thanks!

1

1 Answers

0
votes

First, you can do this by creating an init method and calling it in creationComplete of your renderer. But I wouldn't advise it unless you never plan to use virtualization. The reason I say this is because when the data changes as the user scrolls, you won't see any updates, which will make it look like random old data is showing on the rows of your DataGrid.

Instead, do something like this:

private var _data:*;
private var _dataChanged:Boolean;
override public function get data():*{
    return _data;
}
override public function set data(value:*):void {
   if (value != _data) {
      _data = value;
      super.data=value;
      _dataChanged=true;
      invalidateProperties();
   }
}

override protected function commitProperties():void {
   super.commitProperties();
   if (_dataChanged) {
      //this is just example code of how you'd update your own subcomponents
      someLabel.text = _data['property'];
      //more updating
   }
}

You may have noticed that the Adobe examples show a preference for using data binding for this, and the reason is that if you don't have a strong performance reason to write the type of code shown above, it's a lot easier. Note that for some updates you might need to also override updateDisplayList and/or measure as well.