【问题标题】:Flex: assigning events to dynamically created buttonsFlex:将事件分配给动态创建的按钮
【发布时间】:2011-10-08 13:51:20
【问题描述】:

感谢 wezzy 和过去几天帮助我的其他人。我一直在听取他们的建议,并试图自己解决剩下的问题,但我又被困住了。

我有一个这样的 txt 文件:

button1_label
button2_label
button3_label

我的程序在运行时创建这 3 个按钮并将它们放在一个组中。

protected function onLoaded(e:Event):void {
                var myArrayOfLines:Array = e.target.data.split(/\n/);
                var tempBtn:Button;

                for(var i:Number = 0;i < myArrayOfLines.length;i++){
                    var j:Number = i+1;
                    tempBtn = new Button();
                    tempBtn.id = "btn" + i;
                    tempBtn.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void{
                        var index:uint = parseInt(evt.currentTarget.id.replace("btn", ""));
                                    //TextArea code will go here

trace(text); // Traces null
                    });
                    tempBtn.label = myArrayOfLines[i];
                    btnArray.push(tempBtn);
                    group.addElement(btnArray[i]);
                }
            }

现在您可以从我的代码中看到,我正在尝试让每个按钮都将字符串打印到文本区域。我已经像这样构建了我的新buttons.txt:

button1_label
"Hello"
button2_label
"Goodbye"
button3_label
"Come again"

所以我想做的是让 button1 打印“Hello”。 .txt 文件的所有行都被推入 myArrayOfLines。提前感谢您的帮助。

编辑 完整解释

对不起,我试图简化我的问题,我想我让它更难理解了。我做了一个文本编辑器,而不是运行客户端,没有服务器。我有一组将预定义短语插入 TextArea 的按钮每个按钮都有一个监听器,它执行 myTextArea.insert("sometext"); (但每个按钮的文本不同。用户要求能够创建自己的按钮以插入自己的字符串。我想我会有几个 og 文本输入,用户可以在其中定义标签,以及将插入到按钮单击时的文本区域。我会将标签写入一行,然后将字符串写入下一行。现在我创建了一个具有这种格式的buttons.txt文件,看看它是否可以工作。

最终编辑:工作代码

public function setupBtns(e:Event):void{
            var file:File = File.documentsDirectory.resolvePath("buttons.txt");
            var stream:FileStreamWithLineReader = new FileStreamWithLineReader();
            stream.open(file, FileMode.READ);

            while(stream.bytesAvailable) {
                // this line contains the headers like button1_label etc.
                var label:String;
                // this line contains the string

                if(stream.bytesAvailable) {
                    // this line contains the actual label like "Hello";
                    label = stream.readUTFLine();
                    line = stream.readUTFLine();

                    // strip off the first and last character as they are double quotes
                    line = line.substring(1, line.length-1);

                    var tempBtn:Button = new Button();
                    tempBtn.addEventListener(MouseEvent.CLICK, btnListener);

                    tempBtn.label = label;
                    tempBtn.name = line;
                    btnArray.push(tempBtn);
                    for(var i:Number = 0;i<btnArray.length;i++){
                        group.addElement(btnArray[i]);
                    }
                }
            }
        }           

        protected function btnListener(e:MouseEvent):void{
            mainTextField.insertText(e.target.name);    
            trace(e.target.name);
        }

【问题讨论】:

  • 在询问后续信息时,通常认为编辑原始问题是合适的。我不清楚这是否真的是一个新问题或严重基于这个问题。假设有足够的内容来量化一个新问题(我会让你决定)我删除了你的主题行中的“后续”文本。
  • 很抱歉。我将另一个问题的答案标记为过早解决。我不确定我是否仍然可以发布该问题。这基本上是相同的问题,但有更多细节和代码更改。我应该回到原来的帖子吗?
  • 我很确定您可以取消选择之前选择的答案。如果是这样,最好取消选择答案并编辑旧答案。不过,既然您在这里得到了答案,事情就会变得令人困惑。如果我们离开它,我怀疑有人会抱怨。 [但;从档案的角度来看;上一个问题有一个“不正确/不完全”的答案标记为正确,这可能会让我感到困扰]
  • 1.您的 myArrayOfLines 是否正确填充?你追踪过吗? 2. 为什么不使用 group.getChildIndex(e.currentTarget) 来获取按钮的索引? 3. btnArray 是干什么用的?
  • 这样做的目的是什么?你到底想通过这样做来完成什么?不要拐弯抹角,告诉我们您的用户需要什么行为。

标签: apache-flex actionscript button settings externalizing


【解决方案1】:

试试这个,让我知道结果如何......

编辑:(试试下面的新代码)

        protected function onLoaded(e:Event):void {
            var myArrayOfLines:Array = e.target.data.split(/\n/);
            var tempBtn:Button;

            for(var i:Number = 0;i < myArrayOfLines.length;i=i+1){
                var j:Number = i+1;
                tempBtn = new Button();
                tempBtn.id = "btn" + i;
                tempBtn.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void{
                        myTextArea.text += '\n' + myArrayOfLines[j];
                    });
                tempBtn.label = myArrayOfLines[i];
                btnArray.push(tempBtn);
                group.addElement(btnArray[btnArray.length-1]);
            }
        }           

【讨论】:

  • 越来越近了,但还是有问题。它仍然为每一行而不是每第二行创建一个按钮,例如,它为 Button1 创建一个名为“Hello”的按钮,其中“Hello”应该是 Button1 的属性,而不是单独的按钮。此外,当他们单击时,他们显示的文本是“未定义的”。
  • 不走运。在我的 for 循环中尝试过,并认为您的意思可能是 j=i+2 但都没有奏效。甚至在循环底部尝试 i=i+2 只是为了好玩:)
  • 解释一下“没用”是什么意思 - 它仍然为每一行而不是其他每一行创建一个按钮?
  • 您需要更改“group.addElement(btnArray[i]);”到“group.addElement(btnArray[btnArray.length]);”
  • 不会 group.addElement(btnArray[btnArray.length]);只有当它在循环之外?另外我的意思是没有工作是它仍然为每一行显示一个按钮,并且按钮的输出仍然是'未定义'
【解决方案2】:

首先:不要在 actionscript 中使用匿名函数作为侦听器 - 如果你这样做了,以后就不能删除它们了。

改为使用这样的类方法:

tempBtn.addEventListener(MouseEvent.CLICK, onMouseClick);

private function onMouseClick(evt:MouseEvent):void
{
  if (evt.currentTarget == button1_label)
  {
     // do sth for btn1
  }
  else if (evt.currentTarget == button2_label)
  {
     // do sth for btn2
  }
  // ...
}

编辑

刚刚看到,你使用的是ID,然后把上面的代码改成这样:

if (evt.currentTarget.id == "btn1")

【讨论】: