MediaTemple Hosting

FlashDen - Your Choice for Flash Components and Effects

Bowler Hat Games - Deliriously Delightful

Be a Sponsor

[Bindable] on a read-only getter is unnecessary and will be ignored.

by Josh Tynjala

Sometimes, when you build a Flex application, you encounter a compiler warning that says, "[Bindable] on a read-only getter is unnecessary and will be ignored." If you've seen that message, and you're curious what it means, hopefully I can explain it. In short, the compiler is telling you that it can't actually make that property bindable because it has no way of determining when the property changes.

To understand that better, you should first know a little more about how binding works. Normally, when you make a getter/setter pair bindable, the compiler adds a little extra code for you. Behind the scenes, it dispatches PropertyChangeEvent.PROPERTY_CHANGE to tell the binding system that your property has changed. Basically, it converts your property functions from something like this:

Actionscript:
  1. private var _example:String = "I am the very model of a modern Flex developer";
  2.  
  3. [Bindable]
  4. public function get example():String
  5. {
  6.     return this._example;
  7. }
  8. public function set example(value:String):void
  9. {
  10.     this._example = value;
  11. }

to this:

Actionscript:
  1. private var _example:String = "I am the very model of a modern Flex developer";
  2.  
  3. [Bindable("propertyChange")]
  4. public function get example():String
  5. {
  6.     return this._example;
  7. }
  8. public function set example(value:String):void
  9. {
  10.     this._example = value;
  11.     this.dispatchEvent(new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
  12. }

If you don't have a setter, there's nowhere for the compiler to act smart and determine that your property has changed. If you want a getter without a setter to be bindable, you need to specify an event to be fired when the value returned by the getter changes. Your code should look something like this:

Actionscript:
  1. private var _example:String = "I am the very model of a modern Flex developer";
  2.  
  3. [Bindable("exampleChange")]
  4. public function get example():String
  5. {
  6.     return this._example;
  7. }

Notice the inclusion of the event type in the metadata's parentheses.

That's only the first part, though. Next, you need to actually dispatch the exampleChange event from somewhere in your code. For example, let's say that we change the _example variable when an URLLoader returns a result:

Actionscript:
  1. private function urlLoader_completeHandler(event:Event):void
  2. {
  3.     var loader:URLLoader = URLLoader(event.currentTarget);
  4.     loader.removeEventListener(Event.COMPLETE, completeHandler);
  5.     this._example = loader.data.toString();
  6.     this.dispatchEvent(new Event("exampleChange"));
  7. }

Any time you change _example, you need to dispatch the exampleChange event specified in the metadata so that the the binding system knows about what you did. If you set _example in many different places, you might consider making a private or protected setter that sets _example and dispatches that event, but that's not required.

In summary, the compiler warning goes away when you specify an event type in the metadata. Simply specifying an event type won't update bindings though, you also have to dispatch that event when the underlying variable changes. When the binding system receives your event, it knows to update any component to which your getter is bound.

One extra thing worth mentioning is that any property with Bindable metadata that has no event specified with dispatch the same generic propertyChange event. This means the binding system will have to work harder than needed because it could receive the same event for many different properties. It's a good idea to a create custom event for each property to avoid this limitation. You can see in the Flex framework source code that Adobe has separate events for most, if not all, bindable properties they create.

Like what you just read? Follow @joshtynjala on Twitter.

5 Comments

[Bindable] on a read-only getter is unnecessary and will be ignored. – Josh Talks Flash | Enigmatic Thought

[...] Josh Talks Flash Josh posted about something I just ran into the other day.  The warning [Bindable] on a read-only getter is unnecessary and will be ignored appeared when I was creating a Model for an MVC application.  Since I was using an ArrayCollection [...]

Josh McDonald

Not only does using a custom event name per property improve performance, it makes it trivial to add some [Event] metadata to your class or MXML document, and then you can trigger off property changes easily using events, without using the MXML binding synax or going through BindingUtil.

evden eve

good works

Tink

I’m with Josh.

Everything you mark bindable should have a custom event that’s fired when the property changes.

seanos

To get around this problem I created a setter, but set it private. From an external class this property is still ‘read-only’, but the event does get fired implicitly by the [bindable] private setter function

Leave a Comment

Note: New comments may need to be approved before they appear.

Some HTML allowed in comments: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

To display code in comments: <pre>Code here. May be multiline. Format XML with &gt; and &lt; entities.</pre>