views:

2018

answers:

4

I have a CircleButton class in Actionscript. I want to know when someone externally has changed the 'on' property. I try listening to 'onChange' but it never hits that event handler.

I know I can write the 'on' property as a get/setter but I like the simplicity of just using [Bindable]

Can an object not listen to its own events?

public class CircleButton extends UIComponent

{
 [Bindable]
 public var on:Boolean;

 public function CircleButton()
 {
  this.width = 20;
  this.height = 20;

  graphics.beginFill(0xff6600, 1);
  graphics.drawCircle(width/2, height/2, width/2);
  graphics.endFill();

  this.addEventListener(MouseEvent.ROLL_OVER, rollover); 
  this.addEventListener(MouseEvent.ROLL_OUT, rollout);  

  this.addEventListener('onChange', onOnChange);
 }  

 private function onOnChange(event:PropertyChangeEvent):void {
A: 

You could use BindingUtils.bindSetter()

An example is found here.

Brandon
A: 

Just because it is possible for something to bind to the variable, doesn't mean something is bound to the variable. It's a bit like the event system - just because something can dispatch an event doesn't mean anything is listening.

The Classes around which the Flex binding is based are BindingUtils and ChangeWatcher. When you bind directly in MXML (which just gets converted to AS3 by the compiler) it uses these classes behind the scene to actually establish the binding. I've dug around in ChangeWatcher before and when it looks through the list of potentially bindable items it only dispatches if some object is actually listed as a listener. The whole binding system is a smart wrapper around the event system actually.

The semantics of binding in AS3 instead of MXML are different. Subtle differences (like chaining to child properties of Objects) that just work in MXML require work in AS3 to duplicate the behaviour (probably a result of the code generation between MXML to AS3).

Have a look at this Adobe doc for a little info on ChangeWatcher in AS code.

Personally - I do not use binding outside of MXML since I feel it is clumsy. I would suggest you write a setter function instead since it is more predictable (and very likely performant). I also suggest you read through the source code for ChangeWatcher and BindingUtils. That is definitely some of the most advanced AS3 you are likely to read.

James Fassett
A: 

One of my favorite approaches is the Observe class which is found here. It is essentially using a setter but it is a nice repeatable approach.

Brandon
+3  A: 

If you use the [Bindable] tag without specifying an event type, then when the property changes its value, an event of type: PropertyChangeEvent.PROPERTY_CHANGE, which is the string 'propertyChange', will be dispatched.

Therefore, to be able to register to listen to that event, you need to say:

this.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, onOnChange);

The reason why your listener function was never called is that the event type was not correct.

Note that the listener method will be called when any of the variables marked as Bindable in your class changes, not only 'on'. This event comes with a property called 'property' that indicates which variable was changed.

To avoid being called on each Bindable variable, you need to specify an event in the [Bindable] tag:

[Bindable(event="myOnChangeEvent")]

and dispatch that event manually when you consider that the property is changing (ie: in the setter), though that didn't seem to be what you wanted to do.

Laura
You don't need the `this` reference in front of method calls.
Steve Kuo