Normally in Flex you use a collection like ArrayCollection as the dataprovider for components. I often have data stored as a dictionary whose values I would like to use as a dataprovider.
How would you recommend doing this?
The ideal solution is to not use a dictionary but that doesn't answer your question...
So, if you were forced to use dictionaries, one way to tackle this problem would be to use a function as your "middle man." It can go between your dictionary and the Flex components that care about when it changes.
Of course, with large dictionaries, this may be inefficient but in most cases, the performance should be acceptable.
First, you need a function to convert from Dictionary to ArrayCollection. One of the following working examples could suffice:
Extracting Key/Value Collections from a Dictionary
public function extractKeys(d:Dictionary):ArrayCollection {
var keyList:ArrayCollection = new ArrayCollection();
if(d != null) for(var key:* in d) keyList.addItem(key);
return keyList;
}
public function extractValues(d:Dictionary):ArrayCollection {
var valueList:ArrayCollection = new ArrayCollection();
if(d != null) for each(var value:* in d) valueList.addItem(value);
return valueList;
}
Then, you could actually bind to these functions, themselves! That way, anytime the underlying dictionary is modified, any objects that depend on these functions will get updated. For example:
Binding to Dictionary Values by Using a Function
private var myDictionary:Dictionary; //initialized and used elsewhere
[Bindable(event="dictionaryValueChanged")]
public function extractValues(d:Dictionary):ArrayCollection {
var valueList:ArrayCollection = new ArrayCollection();
if(d != null) for each(var value:* in d) valueList.addItem(value);
return valueList;
}
public function updateDictionary(key:Object, value:Object):void {
myDictionary[key] = value;
dispatchEvent("dictionaryValueChanged");
}
From there you can use THE FUNCTION as your dataprovider. As in:
<mx:DataGrid id="valueGrid" dataProvider="{extractValues()}" />
Whenever your dictionary changes (via the updateDictionary function), it will ultimately trigger an update in the DataGrid!
This is really just an application of a very powerful technique in flex: binding to functions. Once you get the hang of it, there are a wide variety of problems that can be solved with this approach.
I hope that helps someone,
-gMale
EDIT:
I'd have to play around with it but I think you could also eliminate the 'updateDictionary' function by doing something like this, instead:
[Bindable(event="dictionaryValueChanged")]
private var myDictionary:Dictionary; //initialized and used elsewhere
[Bindable(event="dictionaryValueChanged")]
public function extractValues(d:Dictionary):ArrayCollection {
var valueList:ArrayCollection = new ArrayCollection();
if(d != null) for each(var value:* in d) valueList.addItem(value);
return valueList;
}
Other than extending the "dataProvider using" component, or creating a ListCollectionView class that will use a Dictionary as a source; I think you're kind of stuck.
The list based components are designed to display data that comes in some form of order. Dictionary's have no such order.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With