关于Flex事件的一些误区


当你在没有添加事件设置的情形下使用 Bindable 标记时,propertyChange 是将被下发的默认事件类型。 因此,[Bindable] 标记等同于Bindable(event="propertyChange")。 当你没有指定事件字符串时,编译器将为 settergetter 函数创建附加代码,因此建议你添加自己的名称常量以避免产生这种额外的开销。
请看下面绑定语句:
[Bindable]
public var testData:String;

由于没有设置事件名称,编译器将创建下列代码:
[Bindable(event="propertyChange")]         
public function get testData():String
{
  return this._1147269284testData;
}

public function set testData(value:String):void
{
  var oldValue:Object = this._1147269284testData;
  if (oldValue !== value) {
     this._1147269284testData = value;
     if (this.hasEventListener("propertyChange"))                             
        this.dispatchEvent(mx.events.PropertyChangeEvent.createUpdateEvent
        (this, "testData", oldValue, value));
     }
}

正如你看到的那样,mxmlc 创建一个合成 setter 函数,该函数包含发送PropertyChangeEvent 事件的代码。当你更改默认常数,Flex 编译器将不会生成代码,并且你自己应该负责发送该事件。这样,你可以优化侦听代码。如果你没有更改默认常数,则每个 [Bindable] 属性将会发送propertyChange 事件,并且侦听代码必须查询该事件以便确定哪个属性已经更改。如果一个类具有大量的 [Bindable] 属性,则这是一个代价非常高的过程。
一旦你自己设置了事件名称(如下面范例所示),则编译器将会复制该代码。
public static const EVENT_CHANGED_CONST:String = "eventChangedConst"; private var _number:Number = 0; [Bindable(event=EVENT_CHANGED_CONST)] public function get number():Number { return _number; } public function set number(value:Number) : void { _number = value; dispatchEvent(new Event(EVENT_CHANGED_CONST)); }
使用 [Bindable] 标记中的错误事件名称将会导致你的应用程序不能绑定你的属性,而且你甚至还不知道为什么。当你使用具有客户名称的[Bindable] 标记时,下面的范例似乎是个很好的主意:
public static const EVENT_CHANGED_CONST:String = "eventChangedConst"; 
 
private var _number:Number = 0; 
 
[Bindable(event=EVENT_CHANGED_CONST)] 
public function get number():Number  
{                          
   return _number;
}    

public function set number(value:Number) : void 
{                          
   _number = value;
   dispatchEvent(new Event(EVENT_CHANGED_CONST));
}
上面的代码将一个静态属性赋给事件名称,然后使用相同的赋值发送该事件。然而,当该值更改时,绑定功能似乎不能工作。其原因是该事件的名称将是EVENT_CHANGED_CONST 而不是该变量的值。
你的代码应该如下所示:
public static const EVENT_CHANGED_CONST:String = "eventChangedConst"; private var _number:Number = 0; [Bindable(event="eventChangedConst")] public function get number():Number { return _number; } public function set number(value:Number) : void { _number = value; dispatchEvent(new Event(EVENT_CHANGED_CONST)); }
绑定的一个常见的错误是假定绑定是以同步的执行顺序发生的。这将会导致你的应用程序产生告警并且不能绑定你的属性。实际上,ActionScript的事件是以异步的方式执行的。
查看下面的代码范例:
<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
   xmlns:s="library://ns.adobe.com/flex/spark"
   xmlns:mx="library://ns.adobe.com/flex/mx"
   minWidth="1024" minHeight="768"
   creationComplete="creationCompleteHandler(event)">                        


   <fx:Script>

      <![CDATA[
         import mx.events.FlexEvent;
                                  
         [Bindable]
         public var buttonText:String = "Execution order mistake ";                                  
      ]]>
   </fx:Script>
                        
   <s:layout>
      <s:HorizontalLayout />
   </s:layout>

                        
   <s:Label id="label" text="{buttonText}" />

   <s:Button label="{label.text}" />
                        

</s:Application>
上面的代码也许能够运行,然而,它也许不能运行。它假定 Labeltext 属性已经设置完毕,因为 button 组件的label. text 将与Label. text 属性绑定。如果你编译该应用程序,你也会收到一个编译时间告警信息(参见图6)。

图6. 在 Problems 视图显示的编译时间告警信息
下面是另一个范例。它假定第一个 TextInput 控件的值已经设置。这一类型的赋值也会导致编译器产生绑定所需的所有代码。你必须决定是否需要该代码或是否选择直接赋值 (y=35)。
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="1024" minHeight="768"> <s:TextInput id="textInput1" x="10" y="0" /> <s:TextInput id="textInput2" x="0" y="{textInput1.x+25}" /> </s:Application>
在许多情形下,你可以不使用数据绑定很方便地编写你的代码,而是使用事件事件进行赋值操作。你可以通过使用合适的组件生命周期事件或覆盖childrenCreated()initializationComplete() 等组件设置一个值,以便进行赋值操作。此外,你可以 ChangeWatcher 侦听数据的更改,这一方法代价较小。当使用 ChangeWatcher 时,记住在许多情形下,你可以避免使用 ChangeWatcher ,因为你可以人工获得通知。例如,Flex 的所有收集对象具有一个能够广播的 collectionChange 事件,你可以使用该事件在收集对象中人工获得更改通知。
请查看下面范例:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
   xmlns:s="library://ns.adobe.com/flex/spark"
   xmlns:mx="library://ns.adobe.com/flex/mx"
   minWidth="1024" minHeight="768"

   creationComplete="creationCompleteHandler(event)">
                        
   <fx:Script>
      <![CDATA[
         import mx.events.FlexEvent;
                                  
         public var dp:Array = [ { label:"New York", data: "New York" },
         { label:"Miami Beach", data: "Miami Beach" } ];
                                  
         protected function creationCompleteHandler(event:FlexEvent):void

         {
            cb.dataProvider = dp;
         }
                                  
      ]]>
   </fx:Script>
                        
   <mx:ComboBox id="cb" editable="false" width="100" />

                        
</s:Application>
该代码看起来是一个 Flex 应用程序的相当标准代码。然而,这里给出的绑定类型是不需要的。你可以使用事件处理程序的直接赋值方式取代绑定方式。
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
   xmlns:s="library://ns.adobe.com/flex/spark"
   xmlns:mx="library://ns.adobe.com/flex/mx"
   minWidth="1024" minHeight="768"

   creationComplete="creationCompleteHandler(event)">
                        
   <fx:Script>
      <![CDATA[
         import mx.events.FlexEvent;
                                  
         public var dp:Array = [ { label:"New York", data: "New York" },
         { label:"Miami Beach", data: "Miami Beach" } ];
                                  
         protected function creationCompleteHandler(event:FlexEvent):void

         {
            cb.dataProvider = dp;
         }
                                  
      ]]>
   </fx:Script>
                        
   <mx:ComboBox id="cb" editable="false" width="100" />

                        
</s:Application>

你可能感兴趣的:(Flex)