关于模态对话的AS3程序结构

时间:2014-09-05 18:11:11

标签: actionscript-3 structure event-driven dialog

处理异步和事件驱动编程的不熟悉概念(对我来说)我在AS3中使用正确的程序结构。

我想要做的是写一个类,向用户显示带有一些文本的对话框(发送给构造函数)和两个按钮'是'并且没有'。值得庆幸的是,这不再是我的问题。在确定程序的正确结构以获取单击哪个按钮时会出现问题。

让我们说我有Main.as,它在某种程度上称为新的MyDialog,我的理论对话类。我在MyDialog.as中有一个getter,它设置一个变量myButton,默认情况下为0,如果单击是,则为1,如果单击否,则为2。

显然我无法创建对话,然后立即使用getter,用户没有时间点击任一按钮,他们可能会花费任何时间来完成。在我看来,我必须在Main.as中有一个计时器(或帧事件)循环,它不断使用getter来查看myButton,然后在它发生变化时采取相应的行动。

这对我来说似乎不对。我的Main.as必须为我创建的每个对话都有很多状态标志。这将是混乱的,似乎违背事件驱动编程的原则。

我意识到我可以让MyDialog只创建图形,然后在Main.as中点击该对话框中的按钮时会触发一个事件,但这似乎违背了面向对象编程的封装,其中MyDialog应该是完全独立的。

那么,我的可能性是正确的做法还是我忽略了什么?我们将非常感激地对此事提出任何想法。我不是世界上最好的程序员,这些新奇的东西在一段时间后开始伤害我的旧脑袋:)

2 个答案:

答案 0 :(得分:-1)

只需将按钮注册到您希望他们点击时调用的功能。您可以通过构造函数传递它们,如此...

package {
    public class Modal extends Sprite {
        public function Modal(message:String, yes:Function, no:Function) {
            // Draw Background
            graphics.beginFill(0xd9d9d9, 1);
            graphics.drawRect(0, 0, 500, 300);
            graphics.endFill();

            // Create Text
            var txt:TextField = new TextField();
            txt.text = message;
            addChild(txt);

            // Create Yes Button
            var btnYes = new Button();
            addChild(btnYes)
            btnYes.addEventListener("click", yes);

            // Create No Button
            var btnNo = new Button();
            addChild(btnNo)
            btnYes.addEventListener("click", no);
        }
    }
}

请注意,您需要导入相应的类,并且您可能正在为按钮使用完全不同的类,但要点仍然存在。实际上,如果您不想在远程函数上使用事件侦听器,则可以使用自定义参数传递任意函数。

package {
    private var funcYes:Function;
    private var argsYes:Array;

    private var funcNo:Function;
    private var argsNo:Array;

    public class Modal extends Sprite {
        public function Modal(message:String, yes:Function, no:Function, yesArgs:Array = null, noArgs:Array = null) {
            // Draw Background
            graphics.beginFill(0xd9d9d9, 1);
            graphics.drawRect(0, 0, 500, 300);
            graphics.endFill();

            // Create Text
            var txt:TextField = new TextField();
            txt.text = message;
            addChild(txt);

            // Create Yes Button
            var btnYes = new Button();
            btnYes.name = "yes";
            addChild(btnYes)
            btnYes.addEventListener("click", buttonListener);

            // Create No Button
            var btnNo = new Button();
            btnNo.name = "no";
            addChild(btnNo)
            btnYes.addEventListener("click", buttonListener);

            // Store functions and args for later use.
            funcYes = yes;
            argsYes = yesArgs;
            funcNo = no;
            argsNo = noArgs;
        }

        private function buttonListener(e:MouseEvent):void {
            switch (e.currentTarget.name) {
                case "yes":
                    if (argsYes != null) {
                        funcYes.apply(null, args);
                    } else {
                        funcYes();
                    }
                case "no":
                    if (argsNo != null) {
                        funcNo.apply(null, args);
                    } else {
                        funcNo();
                    }
                    break;
            }
        }
    }
}

答案 1 :(得分:-1)

答案,我应该写的是广泛的...这就是为什么我试图把它分解成一些小步骤。

  1. 详细了解OOP的概念。 OOP基本上将应用程序的不同问题分解为应用程序各个方面之间的状态,行为和通信。
  2. 深入了解MVC(S)。 MVC(S)模式(模型视图控制器服务)模式是将应用程序解构为单独层的事实标准模式。
  3. 阅读http://www.robotlegs.org/等框架。这基本上是MVCS的良好实现以及如何应用它。
  4. robotlegs应该让您对如何构建事物有一个很好的了解。困难的部分基本上是让所有组件相互了解。 robotlegs解决这个问题非常好。

    更技术性的答案:你有一个模型,它基本上是一个数据对象。

    package samples.model {
    
      public class SimpleValueModel extends EventDispatcher {
    
        private var _value:int;
    
        public function get value():int { return _value; }
    
        public function set value(v:int):void {
          if (_value == v) return;
          _value = v;
          dispatchEvent(new Event('valueChanged'));
        }
      }
    }
    

    现在每个对数据感兴趣的类,如果它发生变化,需要对它进行引用,以读取它的值:

    private var _model:SimpleValueModel;
    
    public function get model():SimpleValueModel { return _model; }
    
    public function set model(value:SimpleValueModel):void {
      if (_model) _model.removeEventListener('valueChanged', model_valueChangeListener);
      _model = value;
      if (_model) {
        _model.addEventListener('valueChanged', model_valueChangeListener);
      }
      setModel(_model);
    }
    
    protected function setModel(value:SimpleValueModel):void {
      if (value) {
        // value is set
      } else {
        // value is null. 
      }
    }
    
    protected function model_valueChangeListener(event:Event):void {
      setModel(_model);
    }
    

    现在,棘手的部分是传递参考文献。这通过依赖注入(通常使用的另一种设计模式)来完成。 d.i.框架将照顾它(如robotlegs)。

    我希望我能提供一些指示。