Saturday, May 7, 2011

How to watch Bindable vars in Actionscript code

Bindable vars can be watched by the MXML components - but what if we want to see in Actionscript code if bindable var is changed? Is there any way to do that? Of course there is! The class we need is mx.binding.utils.ChangeWatcher. Unfortunately this class has many downsides and generally works worse than binding in MXML, but nevertheless it's still quite useful. As usual let's start with the example (LINK).

First thing to do is to declare some bindable vars:

  [Bindable] public var testString:String = "";
  [Bindable] public var testNumber:Number = 0;
  [Bindable] public var testArrayCollection:ArrayCollection = new ArrayCollection();

Now we need to assign a change watchers for them (one watcher for each var). I think that init() function is good place to do that:

  protected function init():void
  {
    ChangeWatcher.watch(this, "testString", stringChanged);
    ChangeWatcher.watch(this, "testNumber", numberChanged);
    ChangeWatcher.watch(this, "testArrayCollection", arrayCollectionChanged);
  }

Now when you assign a different objects to watched vars the callback functions will be called:

  testString = "test text";
  testNumber = 8;
  testArrayCollection = new ArrayCollection();

At first sight it looks great, but unfortunately there are many situations when this watcher simply won't work. For example adding new item to Array Collection is not watched:

  testArrayCollection.addItem(new Object());

Next very important thing - var that is being watched must be public. Fortunately callback function doesn't have to be.

String and Number vars will throw event only when new value will be different than the old one. So if your Number is let's say 8, and during program execution 8 will be assign to it, the callback function won't be invoked. Usually it's not important, but sometimes, if you have some specific computations in callback function, it could be the issue.

Last thing - you could see that watcher is not instantiated in a standard way (with new operator). Reference to watcher object is returned form watch() function:

  var myWatcher:ChangeWatcher;
  myWatcher = ChangeWatcher.watch(this, "testVar", callbackFunction);

Usually when you use watcher is not important to have reference to it. It could be useful when you want to switch watched var, or if you want to call unwatch() function. You have to call this function when you are about to destroy watcher parent object - for instance if your watcher is in pop up that is going to be closed.

No comments:

Post a Comment