Does Spark List honour the IDropInItemRenderer interfaces?
It appears as though the new spark List component does not honour the IDropInItemRenderer
interface.
Ie - if I implement IDropInItemRenderer
on my renderer, the setter of listData
is never called.
Am I missing something, or is this interface now deprecated?
If so, What is the suggested approach for providing similar dataProvider context information to the renderer?
For example, I want the renderer for the last item in a collection to behave slightly differently.
I see that IItemRenderer
now defines a listIndex
property, however this approach doesn't work without knowing the count of the source dataProvider.
Here's the workaround I've ended up using.
In it's own way, the DataGroup
is dripping Spark's compositional goodness, in that it exposes a rendererUpdateDelegate
property, which you can set with your own class to provide whatever custom functionliaty you're after.
While it's frustrating that the interface got dropped without really being advertised, this approach is much more powerful.
Here's an example class. In my example, I want the last renderer to have it's collapsable
property set to false
:
/**
* Decorates another IItemRendererOwner (eg., a DataGroup) and augments the updateRenderer method
* to set the isCollapsable property */
public class ThreadMessageRendererUpdateDelegate implements IItemRendererOwner
{
private var _dataGroup:DataGroup;
public function get dataGroup():DataGroup
{
return _dataGroup;
}
public function set dataGroup(value:DataGroup):void
{
_dataGroup = value;
if (dataGroup)
{
dataGroup.rendererUpdateDelegate = this;
}
}
public var dataProvider:ArrayCollection;
public function ThreadMessageRendererUpdateDelegate(owner:DataGroup=null)
{
this.dataGroup = owner;
}
public function itemToLabel(item:Object):String
{
return dataGroup.itemToLabel(item);
}
public function updateRenderer(renderer:IVisualElement, itemIndex:int, data:Object):void
{
dataGroup.updateRenderer(renderer,itemIndex,data);
if (renderer is ThreadMessageRenderer)
{
ThreadMessageRenderer(renderer).collapsable = itemIndex < dataProvider.length - 1;
}
}
}
And here's it's example usage:
<fx:Declarations>
<viewer:ThreadMessageRendererUpdateDelegate dataProvider="{dataProvider}" dataGroup="{threadList}" />
</fx:Declarations>
<fx:Script>
<![CDATA[
[Bindable]
public var dataProvider:ArrayCollection
]]>
</fx:Script>
<s:DataGroup height="100%"
width="100%"
dataProvider="{dataProvider}"
itemRenderer="ThreadMessageRenderer"
id="threadList"
>
</s:DataGroup>
Man! Just spent ages trying to find DataGroup.rendererUpdateDelegate(...)
, eventually discovering why I couldn't, courtesy of this SO post.
Anyway, thinking about the (disappearance of) rendererUpdateDelegate
property and your offering a little bit more, I realise neither are really necessary.
DataGroup
has the rendererAdd
event which gives you enough info, at the right time, to do what you want; for example:
...
<s:DataGroup id="dg"
dataProvider="{model.dataProvider}"
itemRenderer="{model.itemRendererFactory}"
rendererAdd="model.updateRenderer(event.data, event.index, event.renderer)">
...
...and in the model
we have:
public function updateRenderer(data:Object, index:int, renderer:IVisualElement):void
{
if (renderer is ICollapsable)
{
ICollapsable(renderer).collapse = index < dataProvider.length - 1;
}
}
Fewer lines of code and clearer intent
链接地址: http://www.djcxy.com/p/34610.html