Why does adding Bindable to a Getter and Setter Method cause a compiler warning?

I've exchanged a few emails with Louise. He saw my 360Flex video on creating Flex Components and had a few questions about how things work. He was creating a component with a selectedValue property. He asked me this:


Why is [Bindable] only needed one time? If I add it before the set function, I get a warning that this is a duplicate. Is it because both functions reference the same property?

Louise answered his own question correctly. The combination of get and set methods create a property on the component. And that property only needs to be declared as Bindable once.

To demonstrate the error, here is a simple code block to cause the warning:


[Bindable]
public function get selectedValue():String{
return _selectedValue;
}

[Bindable]
public function set selectedValue(newValue:String):void{
this._selectedValue = newValue;
}

Just removing the second Bindable will clear that warning right up:


[Bindable]
public function get selectedValue():String{
return _selectedValue;
}

public function set selectedValue(newValue:String):void{
this._selectedValue = newValue;
}

The Bindable Meatadata only needs to be specified once. It is worth noting that you can also specify Bindable on the class; instead of individual properties. If you do that, every "Bindable" in the class definition will generate similar warnings.

I understand that Binding can be a process intensive operation. Does anyone know how making variables Bindable affects performance? I would expect that the performance issues only come into play when the binding actions take place; not by setting variables to binding. But, is that assumption wrong?

As always, I love answering questions; so ask away.

Related Blog Entries

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Roland's Gravatar Wouldn't it make more sense from a logical perspective to add the metadata above the setter? Effectively that's what the metadata is meant for, when the property is changed we want to notify. In other words, when the setter has been called.
From a performance point of view this would be more efficient too:

public function get selectedValue():String{
return _selectedValue;
}
[Bindable(event="selectedValueChanged")]
public function set selectedValue(newValue:String):void{
if (newValue != this._selectedValue)
{
this._selectedValue = newValue;
dispatchEvent(new Event("selectedValueChanged"));
}
}
# Posted By Roland | 12/17/08 7:15 AM
Jeffry Houser's Gravatar Hi Roland,

From a technical stand point I don't think it matters. I find it hard to believe that metadata placement would cause any performance differences. If there was a performance case, I'm sure the Flex Framework code would implement it in the way you suggest.

From an "easy to read code" point of view; the metadata is easiest put before the get/set methods. The get / set methods are just two pieces of code to a "chunk" that make a single property
# Posted By Jeffry Houser | 12/17/08 8:34 AM
Roland's Gravatar Hey Jeffry,

I agree with you, and I wasn't implying that the placement of the metadata would have any affect on performance. I thought from a logical point of view that the metadata ought to be placed above the setter. But your point about the readability is a good one, so it's a matter of taste I guess.
Performance wise it does matter whether you use a generic [Bindable] or a specific [Bindable(event="specificPropertyNameChanged")] though, because it enables bound objects to listen to that specific event instead of the generic propertyChanged event.

cheers,

Roland
# Posted By Roland | 12/17/08 8:41 AM
Jeffry Houser's Gravatar I haven't spent too much time looking at the generated ActionScript code; but when you compile, isn't a "SpecificPropertyNameChanged" event created for each Bindable property on a class?

I didn't think there was a generic propertyChanged event.
# Posted By Jeffry Houser | 12/17/08 9:12 AM
Roland's Gravatar From what I've learnt on my 'blogtravels' so to speak this isn't the case, [Bindable] dispatches a generic event which will eventually slow donw your application if you have a lot of them and a lot of listening objects.

If you want a quick intro into the binding internals then I suggest you watch this little presentation by Michael Labriola:

http://www.slideshare.net/michael.labriola/diving-...

Cheers,

Roland
# Posted By Roland | 12/17/08 9:40 AM
Roland's Gravatar Even better, here's a video of his talk at flex|360

http://link.brightcove.com/services/player/bcpid17...

if you have an hour to spare, its well worth your time I believe.

Roland
# Posted By Roland | 12/17/08 9:47 AM
Jeffry Houser's Gravatar Here are the docs related to this:

http://livedocs.adobe.com/flex/3/html/metadata_3.h...

"If you omit the event name, Flex automatically creates an event named propertyChange."

I always took this to mean it creates an event named [nameoftheproperty]Change . Although I can see why that interpretation would be incorrect.

Michael's preso [and many others from 360Flex] have been on my list of things to watch. Someday I'll get to them.
# Posted By Jeffry Houser | 12/17/08 10:39 AM
john C. Bland II's Gravatar Actually you should put Bindable on the getter since binding will "get" the value and automatically update something. All getters are bindable by default. You don't need to add it so the error is telling you you're using redundant metadata.

Now, you should use [Bindable(name="someEvent")] above your getter to control when to dispatch a binding update. For instance, you might have some complex value that consists of concatenated string. Any time one of the strings changes you want everything bound to your single var to update.

[Bindable(name="myEvent")]
public function get myValue():String{ return field1.text + field2.text + field3.text;}

So, somewhere in a change function or whatever you could merely dispatchEvent(new Event("myEvent")); and it will update everything listening.

As noted above, binding is expensive so don't put it on the class unless you truly want every property to be bindable.

Hope that helps.
# Posted By john C. Bland II | 12/17/08 11:27 PM
Jeffry Houser's Gravatar John,

Do you know if Bindable variables cause performance issues; or just the act of binding? I would expect a variable that has the bindable metatag, but is never bound, will not cause any performance issues.
# Posted By Jeffry Houser | 12/18/08 8:13 AM
Roland's Gravatar It won't have that much direct performance issues, just don't add the [Bindable] metadata to every class blindly, because it will generate getters and setters from every member of your class. If you don't them explicitly for every field than it will increase the size of your class considerably for nothing.
Be especially careful with adding [Bindable] to value objects that can have to be created potentially hundreds or thousands of times. If you don't really need them to be directly bindable than omit the [Bindable] tag.

cheers,

Roland
# Posted By Roland | 12/18/08 10:19 AM
john C. Bland II's Gravatar Yes, adding Binding even to something that isn't "listened" to costs. (as Roland noted)
# Posted By john C. Bland II | 12/19/08 12:03 AM
All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.