PSA: Bindable Setters Don’t Fire!

13 12 2006

I ran into a strange problem in Flex yesterday, and I wanted to share it with you in an effort to make the world a better place. I found that some logic in a setter on my model wasn’t getting executed, which was quite confusing.

First of all, getters/setters are a set of functions in Actionscript (since version 2) that allow you to syntactically treat a function like a property, e.g.:

objectWithoutGetterSetter.setValue(42);
val =
objectWithoutGetterSetter.getValue(); //val=42;
objectWithGetterSetter.value = 42;
val =
objectWithGetterSetter.value; //val=42
// on ObjectWithGetter
public function set value(val:int):void {
this.val = val;
}
public function get value():int {
return this.val;
}

The benefit is readability, mostly, which is all to the good. To the world outside the object it looks like it has a property. In the getter and setter I can execute logic like in a traditional function.

There is another feature of Actionscript, Binding, that works particularly well with getters/setters. It allows me to annotate a setter as “bindable” using the [Bindable] annotation. Elsewhere in the code I can use certain language features to “bind” to that variable, getting changes automagically.

The problem is when I mark a getter/setter pair [Bindable] (works on either the getter or setter) the binding logic decides that if I call the setter with the value that the getter returns (i.e. the current value) the logic in the setter will not execute. IMHO, this breaks the setter pattern. What use is it to have a cool feature like a setter if you can’t depend on the logic in it? You may as well only bind to a traditional property and change that property through a traditional setter function.

I assume the code works the way it does because of performance: Having the whole binding chain execute when the value didn’t change may be inefficient. Perhaps there’re other reasons. Still, it’d be nice to have this behavior explicit, since I may have important logic that needs to execute even if the value doesn’t actually change. I may not know, and I certainly don’t want to have to check each time.

Forewarned is fore-armed and all that. Watch out for bindable getter/setter pairs.

Advertisements