I managed to get DataSelector to work earlier this week and wanted to share how cool it is once you get it working.
Introduction
DataSelector is a mixin class in the Flash MX 2004 Professional v2 component framework (hereafter referred to as the v2 framework). It’s full classpath is:
mx.controls.listclasses.DataSelector
It is used to give a UIComponent the core attributes of working with the common data methods and properties that are prevalent in the v2 framework.
So, if you want your component to have all of the dataProvider methods like addItem, removeItemAt (to interact with a dataProvider thus implementing the DataProvider API), as well as the useful properties to query the View (your UIComponent) such as selectedItem, selectedIndex, and value, this is the class to use. It also gives your UIComponent a dataProvider property, and when it changes, calls invalidate for you. There are a plethora of functions and properties given to you to make more effecient redraws when the model does change.
Why should I care?
Why would you use this? I like it because I don’t feel like proxying all of the DataProvider API calls myself; I can just use the DataSelector, and it automatically gives my class all of those methods instead of me having to write them manually. Secondly, all of the fine grained control over how a dataProvider’s data is changed, as well as keeping track of which item is selected, etc., is all handled for you.
Inheritance vs. Mixin
Why can’t you just inherit from it? As I said, it’s a mixin. Since ActionScript 2.0 does not support multiple inerhitance, you must either use an Interface, Composition, __resolve, or a mixin. A mixin is basically a Decorator that at runtime adds methods at properties to a class’s prototype. Since ActionScript 2.0 supports prototype, this means anything added on a class’ prototype is effectively the same thing as a class member variable or class function.
It manages to compile correctly because a plethora of the base classes of the v2 framework define properties & methods (and the DataSelector template) to ensure the compiler finds the functions and properties that will be there at runtime. So, even though no dataProvider exists in your code at authortime, it will at runtime, so you have to define it so the compiler doesn’t bitch.
Implementing
DataSelector comes with a template that defines all of these properties and methods for you so you can just copy and paste it into your class file. The only two things you have to do to use it are:
- import both DataSelector, and DataProvider
- call their initialize functions in static varible references. This ensures they are actually used and referenced so the compiler exports the class, AND since it’s static, it’ll only happen once; when your class is instantiated
Like so:
import mx.core.UIComponent;
import mx.controls.listclasses.DataSelector;
import mx.controls.listclasses.DataProvider;
class YourClass extends UIComponent
{
public static var mixIt:Boolean = DataSelector.Initialize(YourClass);
public static var mixIt2:Boolean = DataProvider.Initialize(Array);
}
Then, you can just react to any data changes in your draw/size/doLayout function (doLayout assuming you extend View instead of UIComponent).
createClassObject(YourClass, "test", 0);
test.dataProvider = ["one", "two", "three"];
test.addItem({label: "four", data: 4});
test.selectedIndex = 0;
trace(test.selectedItem);
Conclusion
Now, in all fairness some MVC purists will say that this is a violation since this allows your View to be bound to the Model via the dataProvider, which is itself a controversial way of handling data in Flash. I argue that the Controller is the one who bound them so it’s legal. Additionally, in MVP, a modelChanged event is triggered upon using a DataProvider API function like addItem, but the View gets the event and reacts, not the Presenter. Anwyay, I like it and it helps my custom components integrate nicely in the v2 framework.