2011-04-04 65 views
0

我正在研究Flex中动态调查问卷的模板。在我的前一个线程中的更详细的描述HERE如何检查Flex 3中单选按钮的状态?

要创建问卷,我使用嵌套中继器 - 一个用于问题,一个用于答案(因为它们的数量可能会有所不同)。

<mx:Repeater id="r" dataProvider="{questions}"> 
    <mx:Label text="{r.currentItem.question}" width="200"/> 
     <mx:Repeater id="r2" dataProvider="{r.currentItem.answers}"> 
     <mx:RadioButton label="{r2.currentItem.text}" width="200"           
      click="answerHandler(event, event.currentTarget.getRepeaterItem())"/> 
     </mx:Repeater> 
</mx:Repeater> 

要了解我的数据提供商,它可能是最好检查有无我以前的线程的答案 - 不是,如果我尝试在这里解释更容易。

这里的问题是......正如您所看到的,我为每个单选按钮创建了单击事件处理程序,并且我的计划是每次用户选择正确时执行playerScore ++(可以通过检查布尔属性“correct “发送RepeaterItem)。

但是,我现在看到,即使按钮已被选中,我仍然可以多次点击该按钮,即使它没有改变视图中的任何内容,它也会每次增加分数..我也会以处理用户改变主意的情况(我可以为每个好的答案给出+分,并指出错误,但这意味着,如果用户选择了更多错误的答案,我的分数将是负数,而我不想要它)。

因此,只需提交一个提交按钮并检查所有按钮的状态,以及只有在用户单击“提交”之后它们是正确的,方式才会更加简单。可能吗?

回答

0

我建议您参考following sample并将RadioButtonGroup添加到您的转发器组,并听取change事件而不是click。您可以在RadioButtonGroup处听change事件,并检查if (radioGroup.selectedValue.correct)以了解新选择的正确性。见corresponding documentation

要有可能分配radiogroups独特的名称,你必须提取内部中继器与答案到单独的组件。将您的应用程序分解为更小的组件可以使您的应用程序更加清晰易读。您可以将每个MXML文件视为一个类(如在OOP中),但是以声明形式。并且告诉真正的每个MXML组件都是从根节点类继承的类。

让我们看看代码。

首先,我们的内部组件供应答案:

<?xml version="1.0" encoding="utf-8"?> 
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"> 
    <mx:Metadata> 
     [Event(name="rightAnswerEvent", type="AnswerEvent")] 
    </mx:Metadata> 
    <mx:Script> 
    <![CDATA[ 
     import mx.collections.ArrayCollection; 

     [Bindable] 
     public var answers:ArrayCollection; 

     protected function answerGroup_changeHandler(event:Event):void 
     { 
      if (answerGroup.selectedValue.correct) 
       dispatchEvent(new AnswerEvent(AnswerEvent.RIGHT_ANSWER_EVENT)); 
     } 
    ]]> 
    </mx:Script> 

    <mx:RadioButtonGroup change="answerGroup_changeHandler(event)" id="answerGroup" /> 
    <mx:Repeater dataProvider="{answers}" id="answersRepeater"> 
     <mx:RadioButton group="{answerGroup}" label="{answersRepeater.currentItem.text}" 
      value="{answersRepeater.currentItem}" /> 
    </mx:Repeater> 
</mx:VBox> 

它得到answers集合作为输入并引发自定义事件,告知正确答案的一些组件(见Metadata标签)。

我们的自定义事件是非常简单的如下所示:

package 
{ 
import flash.events.Event; 

public class AnswerEvent extends Event 
{ 
    public static const RIGHT_ANSWER_EVENT:String = "rightAnswerEvent"; 

    public function AnswerEvent(type:String) 
    { 
     super(type); 
    } 
} 
} 

所以,现在我们的顶级组件:

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application layout="vertical" xmlns:local="*" 
    xmlns:mx="http://www.adobe.com/2006/mxml"> 
    <mx:Script> 
    <![CDATA[ 
     import mx.collections.ArrayCollection; 

     [Bindable] 
     private var questions:ArrayCollection = new ArrayCollection(); 

     [Bindable] 
     private var scoreCounter:int; 
    ]]> 
    </mx:Script> 
    <mx:Label text="{'Score ' + scoreCounter}" /> 
    <mx:Repeater dataProvider="{questions}" id="questionRepeater"> 
     <mx:Label text="{questionRepeater.currentItem.question}" /> 
     <local:AnswerGroup answers="{questionRepeater.currentItem.answers}" rightAnswerEvent="scoreCounter++" /> 
    </mx:Repeater> 
</mx:Application> 

我省略初始化代码来填充我们的QuestionAnswer域对象与来自XML的数据(请参阅前一个主题)。

所以现在我们有紧凑的模块化代码,其中每个部分都解决了自己的任务。

希望这会有所帮助!

+0

@Constantiner嗯,但我怎样才能创建多少组作为问题?因为如果我在外部中继器之外创建一个RadioButtonGroup,我只能得到一个组。如果我尝试在第一个重复器中创建它,我会收到一个错误:“无法在Repeater中生成初始化代码,这是由于id或数据绑定在不是可视化子组件上的初始化代码。”为了能够访问每个组,我将不得不为每个组分配一个ID。但是使用Repeater时甚至可以这么做吗? – Cela 2011-04-04 17:47:19

+0

@Cela我建议你在独立的MXML组件中提取内部中继器组。 – Constantiner 2011-04-04 18:20:00

+0

@Constantin我真的只是一个初学者......你能解释一下吗?我的独立组件应该如何以及如何引用它?我试图做到这一点,但我收到了很多错误。你能否根据我在我的问题中显示的mxml代码给出答案?谢谢.. – Cela 2011-04-04 19:20:50