Flash-AS3: вызов функции в классе из другого класса (часть 2) через DispatchEvent - PullRequest
0 голосов
/ 19 ноября 2009

Привет, этот вопрос в ответ на комментарий Джоэля Хукса к моему более старому вопросу ( Как вызвать функцию в классе из другого класса? )

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

instance = this; // in Navigation Class
Navigation.instance.introPlayButtonClick(); // in Intro Class

Теперь кажется, что я делаю это не самым лучшим образом или пуристом способом для ООП (могу ощутить дискуссию здесь), поэтому я задаю этот вопрос во второй раз в надежды на то, чтобы понять это правильно.

Проблема

У меня есть 2 класса, вступление и навигация. В классе Intro создана кнопка, которая должна вызывать функцию внутри класса навигации. У меня также есть класс CustomEvent, где я настраиваю пользовательские события. Ниже приведен код, я удалил весь несущественный код, относящийся к этой проблеме.

Вступительный класс

Когда вызывается функция clicked , она отправляет Событие, которое прослушивает класс Navigation.


package src.display
{
import flash.events.*;
 import flash.display.*;

 // ☼ --- Imported Classes
 import src.events.CustomEvent;
 import src.model.Navigation;

 public class Intro extends Sprite 
 {
  private var playBtn:MovieClip;
  private var colorTransform:ColorTransform;

  // ☼ --- Constructor
  public function Intro():void 
  {
      this.addEventListener(Event.ADDED_TO_STAGE, init);
  }

  // ☼ --- Init
  public function init(event:Event):void 
  {
      draw();
      this.removeEventListener(Event.ADDED_TO_STAGE, init);
  }

  public function draw():void 
  {
      playBtn = new PlayThumb;
      playBtn.buttonMode = true;   
      playBtn.x = 552;   
      playBtn.y = 289;
      playBtn.alpha = 1;

      // ☼ --- add button 
      addChild(playBtn);

      // ☼ --- button listeners
      playBtn.addEventListener(MouseEvent.MOUSE_UP, clicked);
  }
  //-----------------------------------------------------
  // ☼ --- My Old Function
  /*private function clicked(e:MouseEvent):void 
  {
      Navigation.instance.introPlayButtonClick(); // Open tab1
  }*/
  //-----------------------------------------------------
  // ♦♦♦ Added to dispatch Event to JStriedl's function ♦♦♦
  private function clicked(e:MouseEvent):void 
      {
      dispatchEvent (new CustomEvent(CustomEvent.INTRO_CLICKED, {}));
      trace("Dispatch Event INTRO_CLICKED");
      }
 }
}

Класс навигации

Это класс навигации, который содержит функцию, которую должен вызывать вводный класс.


package src.model 
{
import flash.events.*;
import flash.display.*;

// ☼ ---Imported  Classes
import src.display.Intro;
import src.model.Fonts;
import src.events.CustomEvent;

public class Navigation extends MovieClip //Needs MovieClip
{  
    public var intro:Intro;
    public static var instance:Navigation;

    // ☼ --- Constructor
public function Navigation()
{
    this.addEventListener(Event.ADDED_TO_STAGE, init);
}

// ☼ --- Init
public function init():void
{
    instance = this;  
    intro = new Intro;
    attachListenerForIntro(intro);
    this.removeEventListener(Event.ADDED_TO_STAGE, init);
}

// ♦♦♦ JStriedl's code ♦♦♦
public function attachListenerForIntro(introToCheckForClick:Intro)
{
    intro = introToCheckForClick;
    intro.addEventListener("introClicked", introPlayButtonClick);
}

// Function that button in Intro needs to call
public function introPlayButtonClick(e:CustomEvent):void
{    
    trace("Navigation function called from Intro");
    intro.removeEventListener("introClicked", introPlayButtonClick);
}
}
}

Проблемы или ошибки

Пока что при нажатии кнопки ничего не происходит :( Я предполагаю, что у меня неправильно настроен EventListener внутри класса навигации?

Ответы [ 2 ]

4 голосов
/ 19 ноября 2009

Обычно контейнер отвечает за вызов функций для своих дочерних элементов.

Если вы хотите, чтобы (в противном случае независимые) братья и сестры взаимодействовали друг с другом, ваш контейнер действует как прокси между ними.

Например, если ваше приложение структурировано так:

container
  |
  +-- introInstance
  |
  +-- navigationInstance
  1. container добавляет прослушиватель для события CustomEvent.INTRO_CLICKED в introInstance.

  2. introInstance вызывает событие CustomEvent.INTRO_CLICKED.

  3. В вызове обработчика событий container navigationInstance.introPlayButtonClick().

Таким образом, вашему Intro классу не нужно ничего знать о вашем Navigation классе, и наоборот, ваш container образует связь между двумя экземплярами.

Краткое примечание: container не обязательно должен быть литеральным DisplayObjectContainer с обоими элементами в списке отображения, он просто должен иметь ссылку на оба экземпляра и знать, что с ними делать.

1 голос
/ 19 ноября 2009

Errr .. единственный способ, которым я мог подумать, - это расширить ваш класс Intro до класса Navigation для правильной работы.

Что-то вроде ..

public class Intro extends Navigation {}
...