views:

8832

answers:

5

Hi,

Is it possible to use EventListener to Listen to a variable and detect when the value of that variable changes? Thanks.

A: 

You used to be able to do something similar in AS2 using Object.watch. I don't see a direct equivalent, but it looks like mx.binding.utils.ChangeWatcher will give you similar functionality for any variables that are bindable.

I don't know of a way to do it in AS3 for non-bindable variables, but if the variable you want to watch is bindable (or if you can modify it to be binadable) then ChangeWatcher might give you what you want.

Herms
+4  A: 

This is quite easy to do if you wrap it all into a class. We will be using getter/setter methods. The setter method will dispatch and event whenever it is called.

//The document class
package
{
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.EventDispatcher;
  public Class TestDocClass extends Sprite
  {
    private var _model:Model;
    public function TestDocClass():void
    {
      _model = new Model();
      _model.addEventListener(Model.VALUE_CHANGED, onModelChanged);
    }
    private function onModelChanged(e:Event):void
    {
      trace('The value changed');
    }
  }
}
//The model that holds the data (variables, etc) and dispatches events. Save in same folder as DOC Class;
package
{
  import flash.events.Event;
  import flash.events.EventDispatcher;
  public class Model extends EventDispatcher
  {
    public static const VALUE_CHANGED:String = 'value_changed';
    private var _someVar:someVarType;
    public function Model():void
    {
      trace('The model was instantiated.');
    }
    public function set someVariable(newVal:someVarType):void
    {
      _someVar = newVal;
      this.dispatchEvent(new Event(Model.VALUE_CHANGED));
    }
  }
}

For the best tutorials check out Lee Brimlow's www.gotoandlearn.com and theflashblog.com

My works are at www.pixeldev.net

Brian Hodge
+1  A: 

That solution works great. The Model package has a typo in the EventDispatcher include. Just update that to events, instead of event, and it is good to go.

A: 

Hi, I am completely new to as3 and have only done a very small amount of very basic as2 scripting in the past. So I was wondering if anyone can help me understand how to use the above example. What could I put in my code to change the variable? Thanks.

A: 

@ Brian Hodge: How do you actually use your example? how do you call the set function ? How do you refer to it ? where do pass the variable to be changed ? .... let say if I want to change the wrapped variable with a button click for example. I have to confess that I tried some other codes and example (getter/setter) type, with dispatchEvent or without...mmm and I can't get over it !(but your example seems to be exactly what I need, just just can't make it work. I get the "The model was instantiated" when I set the function as document class...that's all

I found out, at last
I post it for the nubs like me who are loosing time with this dispatch thing!
In my case the _someVar var has to be data typed as a String (same thing for fornewVal).
OnceTestDocClass is set as your document class... you refer to the Model instantiated like that
_model.someVariable="new stuff";
I was trying to change the value like that
_model.someVariable("new stuff");

U can add some trace actions in the Model class to have a clear demo in the output panel

package
{
  import flash.events.Event;
  import flash.events.EventDispatcher;
  public class Model extends EventDispatcher
  {
 public static const VALUE_CHANGED:String = 'value_changed';
 private var _someVar:String = "default";
 public function Model():void
 {
   trace('The model was instantiated.');
 }
 public function set someVariable(newVal:String):void
 {
   trace ("before " + _someVar);
   _someVar = newVal;
   trace ("after " + _someVar);
   this.dispatchEvent(new Event(Model.VALUE_CHANGED));
 }

  }
}

it's not much but these things can cost some people a whole lot of time =)