Monday, December 18, 2006

getters and setters vs. public properties in Flex

I've been asked several times, why would you use get/set functions instead of public variables in your flex components and classes? Well, there are some great things you can do with getters and setters that you can't do with public variables. On the other hand, there are cases where public variables work better. When using these functions and/or public variables, the code for the caller will be the same:

mycomponent.myValue = 1;


First, lets look at public variables...

[Bindable]
public var myValue : Number

It is better to use public variables when there are no addional actions that need to take place when the value has been changed. If you change the value of "myValue", the bindings will update and everything will be handled accordingly. The value will change, and anything bound to that value will change. In this case, there is no need to use getter/setter methods.

Now, on to getters and setters...

[Bindable(event="myValueUpdated")]
public function set myValue (value:Number):void
{
_myValue = value;
dispatchEvent( new FlexEvent( "myValueUpdated" ) );
}

public function get myValue ():Number
{
return _myValue ;
}

private var _myValue : Number;

First I'll explain the [Bindable(event="myValueUpdated")] statement: This indicates that the data binding to the getter's value should be updated when the event of type "myValueUpdated" is dispatched. You'll notice that when the value is set, this event is dispatched, which would notify and components that are bound to this value.

Now, the rest... The code that I showed above does not have any benefits over the public property, it functions in exactly the same way, but requires more code. The benefits of getter and setter functions is that they enable sequential code execution when the value is changed. You can create your components so that specific functions are executed any time that the value is accessed using get and/or set functions.

Here's an example:

[Bindable(event="myValueUpdated")]
public function set myValue (value:Number):void
{
_myValue = value;
numSets ++;
myFunction();
dispatchEvent( new FlexEvent( "myValueUpdated" ) );
}

public function get myValue ():Number
{
numGets ++;
myOtherFunction();
return _myValue ;
}

private var _myValue : Number;
private var numGets : Number = 0;
private var numSets : Number = 0;

In this example, every time the value is set, the numSets Number is incremented, and the myFunction() function is executed. Likewise, every time the value is accessed using the "get" method, the numGets Number is incremented, and the myOtherFunction() function is executed. There is no limit to what kind of code you can execute here. You can have it dispatch custom events, change styles, create new components, etc... This turns out to be very handy when creating custom Flex components.

I hope you find this helpful! Feel free to contact me with any questions/comments at andrew.trice[ at ]cynergysystems.com.


7 Comments:

Blogger Dan said...

Nicely explained. Thanks

Tue Aug 28, 05:26:00 PM EDT  
Blogger Cornelius said...

hey nice article, i was thinking bout this same thing yesterday - you explained it well.

Cheers

MIKE

Fri Nov 16, 11:50:00 PM EST  
Blogger jakeonfire said...

This post has been removed by the author.

Fri Jan 30, 04:21:00 PM EST  
Blogger jakeonfire said...

it is also useful to be able to cripple the setter to essentially make the property read-only (to outsiders), yet still bindable. you just have to dispatch the FlexEvent("myPropertyUpdated") when appropriate.

Fri Jan 30, 04:23:00 PM EST  
Blogger Freek said...

Finally I've been banging my head against the wall finding this, I though I had some kind of other problem. Why oh why can't I substitute (in you example) "myValueUpdated" for a const class variable (static or not), or in general the event name between the strings for a String variable? Please help out a very confused person ;)

Mon Feb 08, 10:27:00 AM EST  
Blogger Andrew Trice said...

It has to do with the Flex compiler. I've tried many times myself, and gave up after banging my head against the wall. The event metadata is metadata for the compiler and precompiler, not about a class definition or class instance. So, anything defined in there is not within the scope of you classes, and thus the event metadata cannot access attributes of classes or instance.

Mon Feb 08, 10:34:00 AM EST  
Blogger Freek said...

And to think I got that tip to hold the event name in a const in an official Adobe training tutorial, oh well. Anyway, thanks for confirming, it does make sense (somewhat) with Bindable being metadata, thanks for the insight.

Mon Feb 08, 10:48:00 AM EST  

Post a Comment

<< Home