Question

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

Was it helpful?

Solution

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.

(Note: Setters and Getters are treated like properties). You merely assign a value, as opposed to calling a method (e.g someVar = 5 instead of someVar(5); Even though setters / getters are functions/methods, they are treated like properties.

//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));
    }
  }
}

OTHER TIPS

@BrianHodge: 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's 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,and I can't get over it! But your example seems to be exactly what I need, 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, for people like me who are loosing time with this dispatch thing!
In my case the _someVar variable 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 this:

_model.someVariable="new stuff";  

I was trying to change the value like this:

_model.someVariable("new stuff");  

You 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 =)

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top