Binding read-only accessors in Flex

by Ruben

When I first tried to bind a read-only getter-function (see example-code below) the Flex SDK decided to warn me that "[Bindable] on read-only getter is unnecessary and will be ignored.".

private var _someProperty:String = "some value";
 
[Bindable]
public function get someProperty ():String {
   return _someProperty;
}
// generates compile-time warning saying "[Bindable] on read-only getter is unnecessary and will be ignored."
// note that there is no setter-functio

Furthmore, the LiveDocs said the following about the binding getter-only accessors:

If you define just a getter method, you create a read-only property that you can use as the source of a data-binding expression without inserting the [Bindable] metadata tag. This is similar to the way that you can use a variable, defined by using the const keyword, as the source for a data binding expression.
Bindable metadata tag (Adobe Flex LiveDocs)

This is, of course, complete and total bogus. Having a getter-method that is not accompanied by a corresponding setter-method does not necessarily mean that the method its returned value will not ever change, eliminating the option of using the const keyword.

So I had a quick read through the Flex LiveDocs and came up with the following solution:

// the inner internal:
private var __someProperty:String = "some value";
 
// the public property (read-only):
[Bindable(event='somePropertyChanged')]
public function get someProperty ():String {
   return _someProperty;
}
 
// the internal (read/write):
private function get _someProperty ():String {
   return __someProperty;
}
private function set _someProperty (value:String ):void {
   __someProperty = value;
   dispatchEvent(new Event("somePropertyChanged"));
}

As you can see, where the someProperty public getter is made bindable, I used the event attribute of the [Bindable] metadata-tag. You can use the event attribute to assign an Event that will trigger the bindings with a certain member to be refreshed.
I assigned 'somePropertyChanged' as the Event that would refresh the bindings with someProperty.

I also turned the original internal ( _someProperty) into a getter/setter, and created an inner internal for the the internal getter/setter ( __someProperty, two underscores).

Now when the internal setter method ( _someProperty) is called, it automatically dispatches an Event typed 'somePropertyChanged', and thus indirectly triggers the bindings to the public accessor (someProperty) to be refreshed..

This is the cleanest and simplest way of doing this that I could come up with.
However, as far as the databinding mechanism is concerned, keep in mind that only explicitely resetting the value of a variable (for example myVar='new value') counts as change.
Executing a method of a certain variable (for instance myArray.push('new value')) does not count as change, and adjusting the value of an element of a variable (for instance an Array or Object) does not either.

I am currently still trying to find out what the best way is to handle databinding with Arrays or Objects, as soon as I figure it out I'll be sure to put together a follow-up post on this topic.

NOTE: Although, for the sake of clarity, I used the private attribute in the above code-examples, I strongly advise to use the protected in favor of private in almost any case.
This is because a subclass does have access to its superclass' protected properties, whereas it does not have access to its superclass' private properties.