处理异步和事件驱动编程的不熟悉概念(对我来说)我在AS3中使用正确的程序结构。
我想要做的是写一个类,向用户显示带有一些文本的对话框(发送给构造函数)和两个按钮'是'并且没有'。值得庆幸的是,这不再是我的问题。在确定程序的正确结构以获取单击哪个按钮时会出现问题。
让我们说我有Main.as,它在某种程度上称为新的MyDialog,我的理论对话类。我在MyDialog.as中有一个getter,它设置一个变量myButton,默认情况下为0,如果单击是,则为1,如果单击否,则为2。
显然我无法创建对话,然后立即使用getter,用户没有时间点击任一按钮,他们可能会花费任何时间来完成。在我看来,我必须在Main.as中有一个计时器(或帧事件)循环,它不断使用getter来查看myButton,然后在它发生变化时采取相应的行动。
这对我来说似乎不对。我的Main.as必须为我创建的每个对话都有很多状态标志。这将是混乱的,似乎违背事件驱动编程的原则。
我意识到我可以让MyDialog只创建图形,然后在Main.as中点击该对话框中的按钮时会触发一个事件,但这似乎违背了面向对象编程的封装,其中MyDialog应该是完全独立的。
那么,我的可能性是正确的做法还是我忽略了什么?我们将非常感激地对此事提出任何想法。我不是世界上最好的程序员,这些新奇的东西在一段时间后开始伤害我的旧脑袋:)
答案 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)
答案,我应该写的是广泛的...这就是为什么我试图把它分解成一些小步骤。
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)。
我希望我能提供一些指示。