Here's the issue: I've got the list with some dataProvider and itemRendererFunction. I had to decide to use itemRenderFunction because we need to have different renderers for different items in dataProvider. The problem is that when single item in dataProvider changes, I have to refresh whole dataProvider, which is quite problematic in case of big amount of data. Is there any way to refresh a single item in this case?
Example code:
<?xml version="1.0" encoding="utf-8"?>
<s:Application name="list_test"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
click="onApplicationClick(event)"
>
<fx:Script>
<![CDATA[
import mx.core.ClassFactory;
import renderers.*;
import spark.skins.spark.DefaultItemRenderer;
private function itemRendererFunction(item:Object):ClassFactory
{
var rendererClass:Class = DefaultItemRenderer;
switch (item.type)
{
case "typeA":
rendererClass = ItemRendererTypeA;
break;
case "typeB":
rendererClass = ItemRendererTypeB;
break;
default:
break;
}
return new ClassFactory(rendererClass);
}
protected function onApplicationClick(event:MouseEvent):void
{
var item:Object = dp.getItemAt(0);
item.type = "typeB";
dp.itemUpdated(item);
dp.refresh();
}
]]>
</fx:Script>
<fx:Declarations>
<s:ArrayCollection id="dp">
<fx:Object name="Item 1"
type="typeA"
/>
<fx:Object name="Item 2"
type="typeA"
/>
<fx:Object name="Item 3"
type="typeB"
/>
</s:ArrayCollection>
</fx:Declarations>
<s:List id="list"
labelField="name"
itemRendererFunction="itemRendererFunction"
horizontalCenter="0"
verticalCenter="0"
useVirtualLayout="true"
height="300"
dataProvider="{dp}"
>
</s:List>
</s:Application>
I've placed some traces on addToStage event handlers in item renderers classes. All of them are called at every single click.
As discussed in this SO post, you'll want to avoid returning a new instance of ClassFactory for every invocation of your itemRendererFunction:
private var itemRendererTypeA:ClassFactory = new ClassFactory(ItemRendererTypeA);
private var itemRendererTypeB:ClassFactory = new ClassFactory(ItemRendererTypeB);
private function itemRendererFunction(item:Object):ClassFactory
{
switch (item.type)
{
case "typeA":
return itemRendererTypeA;
break;
case "typeB":
return itemRendererTypeB;
break;
default:
break;
}
}