AS3 - Могу ли я обнаружить изменение значения переменной с помощью addEventListener?

Можно ли использовать EventListener для прослушивания переменной и определить, когда изменяется значение этой переменной? Спасибо.

Ответ 1

Это довольно легко сделать, если вы завернете все это в класс. Мы будем использовать методы getter/setter. Метод setter будет отправлять и события всякий раз, когда он вызывается.

(Примечание: Setters и Getters обрабатываются как свойства). Вы просто назначаете значение, а не вызов метода (например, someVar = 5 вместо someVar(5);. Даже если сеттеры/геттеры являются функциями/методами, они обрабатываются как свойства.

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

Ответ 2

@BrianHodge: Как вы на самом деле используете свой пример? Как вы называете функцию set? Как вы к этому относитесь? Где передать переменную, которую нужно изменить..?

Скажем, если я хочу, например, изменить обернутую переменную нажатием кнопки. Должен признаться, что я пробовал другие коды и пример (getter/setter), с dispatchEvent или без, и я не могу преодолеть это! Но ваш пример, похоже, именно то, что мне нужно, просто не может заставить его работать.

Я получаю The model was instantiated, когда устанавливаю функцию как класс документа. Это все.

Я узнал, наконец, для таких людей, как я, которые теряют время с этой отправкой! В моем случае переменной _someVar должны быть данные, напечатанные как String (то же самое для fornewVal).

OnceTestDocClass устанавливается как ваш класс документа; вы ссылаетесь на модель, созданную таким образом:

_model.someVariable="new stuff";  

Я пытался изменить значение следующим образом:

_model.someVariable("new stuff");  

Вы можете добавить некоторые действия трассировки в класс Model, чтобы иметь четкую демонстрацию на панели вывода:

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

Это не так много, но эти вещи могут стоить некоторым людям много времени =)

Ответ 3

Вы использовали, чтобы сделать что-то подобное в AS2, используя Object.watch. Я не вижу прямого эквивалента, но он выглядит как mx.binding.utils.ChangeWatcher даст вам аналогичную функциональность для любых переменных, которые Привязываемое.

Я не знаю, как это сделать в AS3 для не привязываемых переменных, но если переменная, которую вы хотите смотреть, является связующей (или если вы можете изменить ее, чтобы быть бинарной), то ChangeWatcher может дать вам то, что вы хотите.