DataSelector: Data Interaction Core of the v2 Framework for Your Views

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:

  1. import both DataSelector, and DataProvider
  2. 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
{
        // your DataSelector template will go here
        
        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.

8 Replies to “DataSelector: Data Interaction Core of the v2 Framework for Your Views”

  1. On a side note, Its been weird to me that addItem is a method of the component. It seems like dataProvider would have been a property, so if you wanted to access all those things you would have gotten it by going through it. In a purity aspect, you woudn’t even do that you would access the dataprovider directly in the controller or where it lived.

  2. I agree, I never use component methods, and instead mess with the dataprovider directly. The changes are sent to the View to then update.

    However, there are cases where you want to quickly show some data in a View without having to go through the process of simply creating a dataProvider for it. This is nice because its fast, and at a later date, if you are so inclined, you can grab the data you added to the View out and repurpose elsewhere.

    Not sure if that was the design decision behind it; perhaps to help in writing binding code? :: shrugs ::

  3. sir
    i want to connectivity with flash file into VB form just pass two string value in vb form. Is it possible or not just tell know if yes how can i use it help

    Regards
    Deepak singh

  4. Only way to currently talk out of the Flash Player is fscommand, and you can only send 2 strings. So:

    var foo:String = ‘moo’;
    fscommand(‘hey’, foo);

    You could do a comma dilmitted list in the 2nd parameter.

  5. Dear Jesse,

    I have found some very good and useful infomation. Thanx a bunch.
    Maybe you can help me out. I am currently trying to develop V2 Components myself extending UIComponent and starting with a simple Button.
    Now I am wondering how to set skins at runtime. I have been studying the Code of simpleButton and there setSkin() is used to set a skin at runtime. ( I wish it were that easy :) but for me it doesnt work it only sets the skin once at init.
    var skin = setSkin(tagMap[s], s, {_x:0, _y:0, styleName:this});
    and as mm i dont call it directly but call viewSkin and pass the skin variable. and it works at init but not at runtime. My fault ? Can you tell me wether I am doing this correctly ?
    If so , how can i do it right ?

    help greatly appreciated
    amir

  6. I think setSkin and it’s ilk merely register the skin, they don’t actually change it. Somewhere in the bowls of the CSS classes, there is a way to respond to them. So, when you do:

    setStyle(‘themeColor’, ‘haloBlue’);

    The CSS styles all change, and you can redraw since you get an event for it. I think the example for Halo is at:

    mx.skins.halo.Defaults. There, you’ll see the default color values, and then next to it is ButtonSkin. If you can find out where ButtonSkin is actually used, I think you’ll find where skins are used from those, and thus, find the function that allows you to change them at runtime. Shooting from the hip here, just woke up…

  7. yawn…
    okay, thanx i’ll try that out, and one more thing while I was sleeping last night, the code from mm ran through my head, i think i got it how mm changes the button skins.
    A TagMap is used to specify the depth of each skin, also every Button state is registered in a var one time as a String and once as an Object, and on setState the appropriate skins get attached. Also setSkin() is never called actually, but instead viewSkin() or ‘myCustomSkinnningMethod()’ is invoced and retrieves the skinName based on two vars and sets the curentSkin’s _visible prop to false and the new skin to true.
    But I never thought of CSS for I have always developed for the 6 Player. I’ ll let you know if it worked.
    thanx again for the support ! :) everything helps to shed some light in the mysterious realms of the V2 Component Framework.
    have good day and happy hacking
    sincerely amir

  8. I think setSkin is actually called in the skins themselves. Look in the skins in here:

    C:\Program Files\Macromedia\Flash MX 2004\en\Configuration\ComponentFLA\StandardComponents.fla

    You’ll see some weird style & skin calls in there, even #initclips!

Comments are closed.