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

Actionscript 3 关于模态对话的AS3程序结构,actionscript-3,structure,event-driven,dialog,Actionscript 3,Structure,Event Driven,Dialog,在处理我不熟悉的异步和事件驱动编程的概念时,我很难在AS3中找到正确的程序结构 我想做的是编写一个类,它向用户呈现一个对话框,其中一些文本被发送到构造函数,还有两个按钮“是”和“否”。谢天谢地,这对我来说已经不是问题了。当决定程序的正确结构以获取已单击的按钮时,问题就出现了 假设我有Main.as,它在某个点上称为newmydialog,我的理论对话课。我在MyDialog.as中有一个getter,它设置了一个变量myButton,默认值为0,单击“是”时为1,单击“否”时为2 显然,我不能创

在处理我不熟悉的异步和事件驱动编程的概念时,我很难在AS3中找到正确的程序结构

我想做的是编写一个类,它向用户呈现一个对话框,其中一些文本被发送到构造函数,还有两个按钮“是”和“否”。谢天谢地,这对我来说已经不是问题了。当决定程序的正确结构以获取已单击的按钮时,问题就出现了

假设我有Main.as,它在某个点上称为newmydialog,我的理论对话课。我在MyDialog.as中有一个getter,它设置了一个变量myButton,默认值为0,单击“是”时为1,单击“否”时为2

显然,我不能创建一个对话,然后立即使用getter,用户将没有时间单击任何一个按钮,他们可能需要任何时间来这样做。在我看来,我必须在Main.As中有一个计时器或帧事件循环,它不断地使用getter查看myButton,然后在它发生变化时相应地进行操作

我觉得这是不对的。我的Main.as必须为我创建的每个对话都有许多国旗。这将是混乱的,似乎违背了事件驱动编程的原则

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


那么,我的可能性是正确的方法还是我忽略了什么?如对此事有任何意见,将不胜感激。我不是世界上最好的程序员,过了一段时间,这种新奇的东西开始伤害我的旧脑袋:

只需将按钮注册到您希望它们在单击时调用的函数。你可以像这样通过构造函数传递它们

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

答案,我应该写的是一条通往。。。这就是为什么我试着把它分解成一些小步骤

了解更多关于OOP的概念。OOP基本上是将应用程序的不同关注点分为状态、行为和应用程序各个方面之间的通信。 充分了解MVC。MVCS模式Model View Controller服务模式实际上是将应用程序分解为不同层的标准模式。 阅读类似的框架。这基本上是一个很好的MVCS实现,以及如何应用它。 机器人腿应该为你提供一个关于事物应该如何构造的好主意。最困难的部分基本上是让所有组件相互了解。机器人腿很好地解决了这个问题

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

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.框架将像机器人腿一样处理它


我希望我能提供一些建议。

这就是活动的目的。单击任何按钮时发送事件并捕获它们,然后采取行动。感谢您的回答。我当然有很多书要读。特别有兴趣了解机器人腿。我本想给两个当前答案打勾,但网站不允许。谢谢,我没有考虑传递函数的可能性,这似乎可以满足OOP和事件驱动编程的要求。这真是太聪明了。我在某一点上认为我需要使funcYes=yes;而funcNo=no?在.apply方法中,'args'变量应该是argsYes和argsNo吗?我完全忘了在第二个oops示例中添加它。正确,您现在可以在构造函数的末尾看到相应的赋值。