Event

1.在FlashPlayer創建完一個組件時,它會分派一個creationComplete事件。DisplayObject 類是 EventDispatcher 類的子類,這意味者每一個 DisplayObject 都可以註冊事件監聽器,並在事件發生的時候進行相應的處理。

 

2.用戶自定義的類可以業務邏輯中分派事件。

 

3.EnterFrame事件由AVM觸發,並以程序中幀的刷新速率進行觸發。

   addEventListener(Event.ENTERFRAME, onEnteringFrame);

 

4.可以分派自定義事件。

 

 

JAVA中的事件監聽者是對象,AS3中事件監聽者只是Function。如果要在自定義的AS3類裏分派事件,這個類必須是EventDispatcher的子類,或實現了IEventDispathcer接口。

 

 

JAVA中,將產生某個事件的對象稱爲這個事件的source。但在Flex中,可以說所有的事件都是FlashPlayer產生的。FlashPlayer9對事件模型的實現是建立在W3C的DOM事件模型上的,一個事件的生命週期有三個階段:捕獲、target、bubbling。

 

capture:在這一階段,Flashplayer從display list的根開始檢查,一直到目標組件,來看看有沒有任何父組件對這一事件感興趣。默認情況下,目標組件的父組件會忽略這一事件。

 

target:在這一階段,事件對象的屬性將會設置至目標組件中,並且所有註冊的對這一事件的監聽器將會獲得這一事件對象。

 

bubbling:最後,事件流將會從目標對象沿原路返回到根層組件,並通知在capture階段確定的對這事件感興趣的對象。

 

但是用戶自定義的事件並不會經歷上述的三個階段,不過AS3開發者可以建立自定義的事件分派者來實現這三個階段。

 

 

例如下面的代碼:

<?xml version=”1.0” encoding=”utf-8”?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” >
  <mx:Panel x=”17.5” y=”20” width=”209” height=”142”  layout=”absolute”
      click=”trace(‘click event in the Panel’)” title=”Just a Panel”>
  <mx:Button label=”ClickMe” x=”60.5” y=”38”
      click=”trace(‘click event in the Button’)”/>
  </mx:Panel>
 
</mx:Application>

 

將會在控制檯輸出:

click event in the Button
click event in the Panel

 

 

默認情況下,在capture階段是不會執行事件的監聽器的,但是可以通過設置來讓監聽器在capture階段就被執行:myPanel.addEventListener(MouseEvent.CLICK, panelClickHandler, true);這裏第三個參數就是指明要在capture階段執行監聽器。如果註冊兩遍,一遍帶參數true,一遍不帶,那麼在capture階段和bubbling階段都會執行監聽器。

 

我們還可以阻止事件的分派:

private function panelClickHandler(event:MouseEvent) :void{
             var badNews: Boolean = true; // a flag to emulate a bad situation
             if (event.eventPhase == EventPhase.CAPTURING_PHASE){
               trace (“Capturing phase: click event in the Panel”);              
               if (badNews){
                  trace (“Capturing phase: Bad news. Will not propagate click to  Button”);
                  event.stopPropagation();
               }
             }else {
               trace (“click event in the Panel”);
             }
            }

 

 

需要強調的是,一個組件並不是將事件發送到任何其他的組件。它僅僅是將這個“令人激動的新聞”廣播到事件分派器。如果有任何組件對處理這個事件有興趣的話,它必須爲這個事件註冊一個監聽器。

 

在MXML中使用自定義事件時,要使用元數據標籤:

<?xml version=”1.0” encoding=”utf-8”?>
<mx:Button xmlns:mx=”http://www.adobe.com/2006/mxml”
  width=”104” height=”28” cornerRadius=”10” fillColors=”[#00ff00, #00B000]”
  label=”Add Item” fontSize=”12” click=”greenClickEventHandler()”>
 
  <mx:Metadata>
    [Event(name=”addItemEvent”, type=”flash.events.Event”)]
  </mx:Metadata>
 
  <mx:Script>
    <![CDATA[
        private function greenClickEventHandler():void{
              trace(“Ouch! I got clicked! Let me tell this to the world.”);
              dispatchEvent(new Event(“addItemEvent”, true));// bubble to parent
        }
    ]]>
  </mx:Script>
</mx:Button>

在上面的代碼中,當點擊這個button時,這個組件會將自定義的addItemEvent事件分派到“外面的世界”,它不用知道其他的事情。下面一段代碼註冊了一個監聽器來監聽這個事件。

<mx:TextArea xmlns:mx="http://www.adobe.com/2006/mxml"  backgroundColor="#ff0000"  creationComplete="init()">
 <mx:Script>
    <![CDATA[
        private function init():void{
         parent.addEventListener("addItemEvent",addItemToCartEventHandler);
        }
 
       private function addItemToCartEventHandler(event:Event):void{
         this.text+="Yes! Someone has put some item inside me, but I do not know what it is. /n";
       }
    ]]>
  </mx:Script>
</mx:TextArea>

然後在application中這樣寫:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:ctrl="controls.*" layout="vertical">
 <ctrl:CustomEvent_LargeGreenButton addItemEvent="greenButtonHandler(event)"/>
 <ctrl:CustomEvent_BlindShoppingCart width="350" height="150" fontSize="14"/>
 <mx:Script>
      <![CDATA[
        private function greenButtonHandler(event:Event):void{
         trace("Someone clicked on the Large Green Button!");
        }
        ]]>
    </mx:Script>
</mx:Application>

如果在JAVA中,這樣的代碼要寫成:

LargeGreenButton.addClickEventListener(

    new XXXListener(){

        public void action() {

              這裏往ShoppingCart中添加物品;

        }

    });

這樣就把LargeGreenButton和ShoppingCart粘合起來了,FLEX裏就去掉了這種粘合。

 

========================================================================

 

Flex中的事件機制 <script></script> ofengofeng | 更新時間:2008-07-11 08:49:25 | 點擊數:685

 

一. 事件簡介
事件可以由外設觸發, 比如:鍵盤,鼠標, 也可能是外部輸入, 比如:web service的返回.
事件還能由組件的外觀和生命週期發生變化時觸發, 比如:組件的創建或者改變大小.
所有用戶與應用交互都會產生事件.用戶沒有直接與應用交互也可能產生事件, 比如:數據裝載完畢.
你可以在程序中使用事件監聽器監聽這些事件. 事件監聽器是函數方法用於響應指定的事件. 有時也稱之爲事件處理器.
Flex的事件模型基於DOM3事件模型.
組件產生派發事件並消費(監聽)其他事件.如果一個對象想要了解其他對象事件的信息, 可以註冊一個監聽器.
當事件發生時,對象派發此事件到所有註冊過的監聽器中.
組件有Flex提供的內建事件. 也可以使用派發-監聽模型定義自己的事件監聽器, 並指定監聽器監聽何種事件.
二. 事件流簡介
當一個事件被派發出來時, 事件對象從根節點開始自上而下開始掃描display list, 一直到目標對象, 檢查每個節點是否有相應的監聽器.
目標對象指的是display list中產生事件的對象. 比如:
<mx:Panel>
<mx:HBox>
<mx:VBox>
<mx:Button />
</mx:VBox>
</mx:HBox>
</mx:Panel>
如何此時 resize了VBox, 則會從根(Application)開始, 下來檢查Panel, HBox, 直到目標對象-產生resize事件的VBox爲止.

三. 事件的派發
Flex中可以通過dispatchEvent()方法手工派發事件, 所有UIComponent的子類都可以調用此方法.
語法:
objectInstance.dispatchEvent(new Event("event_type"):Boolean
參數event_type是Event對象的type屬性. 函數的返回值總是True.
可以使用此方法派發任意事件, 而不僅僅是用戶自定義事件, 比如: 可以派發一個Button的Click事件.
var result:Boolean = buttonInstance.dispatchEvent(new Event(MouseEvent.CLICK));

在Flex應用中不是必須對新派發的事件進行處理, 如果觸發了一個事件, 而沒有對應的Listener時,Flex忽略此事件.
如果想給Event對象添加新屬性, 就必須繼承Event類,然後定義新屬性

四.事件的傳播:
事件觸發後, Flex有3個檢測事件監聽器的階段, 3個階段的發生的順序如下:
1. 捕獲
2. 目標
3. 上浮
在任意一個階段, 節點們都有機會操作事件. 比如: 用戶點擊了一個在VBox中的Button,
在捕獲階段, Flex檢查Application對象(根節點)和VBox是否有監聽器處理此事件. Flex然後在目標階段觸發按鈕的監聽器.
在上浮階段, VBox和應用以與捕獲階段相反的順序再次獲得機會處理事件.
在Actionscript3.0中,你可以在任意目標節點上註冊事件監聽器. 但是部分事件會被直接傳給目標節點,比如Socket類.
捕獲階段的節點順序是從父節點到子節點的, 而上浮階段剛好相反.
捕獲事件缺省是關閉的,也就是說如果要捕獲事件, 必須顯式指定在捕獲階段進行處理.
每一個Event都有target和currentTarget屬性, 幫助跟蹤事件傳播的過程.

捕獲階段:
在捕獲階段,Flex在顯示列表中檢查事件的祖先是否註冊了事件的監聽器. Flex從根節點開始順序而下.
大多數情況中, 根節點是Application對象. 同時, Flex改變事件的currentTarget值.
缺省情況下, 在此階段,沒有容器監聽事件. use_capture參數的值是False,在此階段添加監聽的唯一方法是在調用add_listener時,
傳入一個爲True值的use_capture參數, 比如:
myAccordion.addEventListener(MouseEvent.MOUSE_DOWN, customLogEvent, true);
如果是在Mxml中添加監聽, Flex設置此參數爲False, 沒有辦法進行修改.
如果設置了use_capture爲True, 那麼事件將不會上浮. 如果既想捕獲又想上浮就必須調用 addEventListener兩次.
一次use_capture參數爲true, 一次爲false;
捕獲很少使用, 上浮的使用更爲普遍.

目標階段:
在目標階段, Flex激發事件的監聽程序, 不檢查其他的節點.

上浮階段:
事件只在bubbles屬性爲True時才進行上浮. 可以上浮的事件包括: change, click, doubleClick, keyDown, keyUp, mouseDown, mouseUp.
在上浮階段, Flex改變事件的currentTarget屬性, 而target屬性是初始派發事件的對象.

查詢事件階段:
使用事件的eventPhase可以獲得事件當前的階段,
1: CAPTURE_PHASE
2: AT_TARGET
3: BUBBLING_PHASE
示例: private function determineState(event:MouseEvent):Void { Debug.trace(event.eventPhase + ":" + event.currentTarget.id); }

停止傳播:
使用下面兩個函數停止事件的傳播:
stopPropagation()
stopImmediatePropagation()

 
件是一個非常有用的功能,通常用於信息傳遞交互大大提高程序編寫的靈活性。在高級語言中都會集成這方面特性;Flex也不例外幾乎所有控件中都集成了大量的事件,如果Button的Click事件等。但實際應用中控件自有的事件是不能滿真實需要的,特別在自己編寫自定義控件時,自定義控件內部信息的改變如何及時通知所在的容器變得很更要;這個時候自定義事件就起到它的作用。

       在Flex中定義事件有兩中情況,分別是ActionScript和MXML中定義。

       在ActionScript中定義:

 
CODE:
[Event(name="myEnableEvent", type="flash.events.Event")]

public class MyComponent extends UIComponent

{

           ...

}

在MXML中定義:

 

CODE:
<mx:Metadata>

    [Event(name="DataChange", type="DataChangeEvent")]

</mx:Metadata>

DataChangeEvent事件參數的定義:

 

CODE:
import flash.events.Event;

public class DataChangeEvent extends flash.events.Event

{

       public function DataChangeEvent()

       {

              super("DataChange");

       }

       public var Data:Object;

}

 

在自定義控件中定義和觸發事件:

 

CODE:
<?xml version="1.0" encoding="utf-8"?>

<mx:Form xmlns:mx="http://www.adobe.com/2006/mxml" width="212" height="56">

<mx:Metadata>

        [Event(name="DataChange", type="DataChangeEvent")]

    </mx:Metadata>

<mx:Button label="Button" click="Change()"/>

       <mx:Script>

              <![CDATA[

                     function Change():void

                     {

                            this.dispatchEvent(new DataChangeEvent());

                     }

              ]]>

       </mx:Script>

</mx:Form>

容器接收相關自定義控件事件:

 

CODE:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:ns1="*">

      

       <ns1:EmployeeCombo x="146" y="132" DataChange="onChange(event)" >

       </ns1:EmployeeCombo>

       <mx:Script>

              <![CDATA[

                     import mx.controls.Alert;

                     function onChange(e:DataChangeEvent)

                     {

                           

                     }

              ]]>

       </mx:Script>

</mx:Application>

其實自定義事件的現實也很簡單,但起着非常重要的作用;正是因爲有了事件的機制,使得大部分重複的功能抽取到自定義控件中,從而達到一個很高的代碼重用性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章