<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    有才華的人,別忘記給滋潤(rùn)你的那塊土壤施肥

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      28 隨筆 :: 5 文章 :: 147 評(píng)論 :: 0 Trackbacks
    文章來自:http://www.riachina.com/showtopic-8747.html
    關(guān)于flex事件的講解

    一.引

    很多新人對(duì)Flex的事件機(jī)制都不太熟悉,在使用過程中難免會(huì)出現(xiàn)各種問題,這是一個(gè)非常普遍的問題,為了更快更好的幫助大家,將介紹一下Flex中事件的各種機(jī)制和用法。

    Flex的精髓之一就是事件和綁定機(jī)制,了解之后,能幫助大家更靈活的設(shè)計(jì)程序,也對(duì)新手上路有一定的幫助。

    講解可能不太系統(tǒng),也不全面,有很多沒有深入。如果高手看到后有疑問,歡迎指正。當(dāng)然各位也可以提出自己的看法,或者經(jīng)驗(yàn)分享,謝謝。

    二.事件機(jī)制介紹

    1.      什么是事件機(jī)制

    事件可以看作是一種觸發(fā)機(jī)制,當(dāng)滿足了一定的條件后,會(huì)觸發(fā)這個(gè)事件。比如MouseEvent就是指的當(dāng)鼠標(biāo)進(jìn)行操作之后觸發(fā)的一系列的事件。很多控件中都有click事件,這個(gè)事件就是一個(gè)MouseEvent的實(shí)例,當(dāng)點(diǎn)擊鼠標(biāo)后,系統(tǒng)會(huì)自動(dòng)拋出一個(gè)名稱為click的MouseEvent事件(這種方法我們將在后面介紹到)。如果此時(shí)在click上注冊(cè)一個(gè)方法,那么觸發(fā)該事件時(shí)就會(huì)執(zhí)行這個(gè)方法。

    大致示意圖
     
    該示意圖對(duì)應(yīng)的Flex主應(yīng)用的mxml代碼
    <mx:Script>
              
    <![CDATA[
                    import mx.controls.Alert;        
                    private 
    function clickHandler(e:MouseEvent){
                          Alert.show(e.currentTarget.toString());
                    }

              ]]
    >
    </mx:Script>
    <mx:Button id="testBtn" click="clickHandler(event)" label="測(cè)試">
    </mx:Button>



    在我們寫代碼時(shí),編輯器的代碼補(bǔ)全提示列表中,有很多不同的圖標(biāo),如圖

    那些帶有閃電的就是事件,三個(gè)小塊的就是樣式,空心圓圈的是屬性,實(shí)心圓點(diǎn)的是公有方法,還有一個(gè)是效果。

    我們能在這個(gè)列表中看到的事件,我把它稱之為事件注冊(cè)通道。(官方仍然稱它為事件,但是它又和普通的事件含義不同。關(guān)于事件注冊(cè)通道會(huì)再下面講述到)

    2.      事件注冊(cè)通道

    上面說到了,這些通道是只能在mxml的代碼提示中可以看到的,他的作用就是給mxml組件提供 事件觸發(fā)時(shí)所執(zhí)行的方法的注冊(cè)通道,而且能在代碼提示中可見,這樣給組件提供了很大的抽象的好處,我們可以很清楚的告訴組件的使用者,組件里包含哪些事件給你調(diào)用。
    為什么把他區(qū)別對(duì)待?除了代碼提示外,他還有一些實(shí)現(xiàn)上的不同。

    Button的click事件是繼承自核心類InteractiveObject,遺憾我們看不到他的源碼,但是說明了“事件注冊(cè)通道”是可以繼承的。

    我們會(huì)在自定義事件中講述到如何聲明“事件注冊(cè)通道”。

    3.      事件觸發(fā)方法

    注冊(cè)通道中如果填入了函數(shù),那么就代表觸發(fā)該事件時(shí),會(huì)執(zhí)行這個(gè)方法。

    click="clickHandler(event)"

    我們看到這個(gè)方法有一個(gè)event對(duì)象作為參數(shù)傳入,新人可能會(huì)問到,這個(gè)event對(duì)象哪里來的?我也沒聲明這個(gè)變量啊。他實(shí)際上是注冊(cè)通道傳給他的,默認(rèn)變量名就是event。我們?nèi)绻朐谑录|發(fā)時(shí)傳其他的參數(shù),可以通過自定的事件對(duì)象來實(shí)現(xiàn)。

    這個(gè)對(duì)象就是這個(gè)組件分發(fā)的事件對(duì)象,即type為“click”的MouseEvent的一個(gè)實(shí)例。

    這個(gè)event對(duì)象包含了觸發(fā)該事件時(shí)的各種信息,比如觸發(fā)事件對(duì)象是哪個(gè),監(jiān)聽對(duì)象是哪個(gè),觸發(fā)時(shí)鼠標(biāo)點(diǎn)在哪里等等,不同的event類會(huì)包含不同的屬性,比如KeyboardEvent包含了鍵盤點(diǎn)擊了哪個(gè)鍵。

    我們也可以通過自定義一個(gè)事件類,來傳遞我們自己想要的各種信息。(這在后面將介紹到)

    4.      事件分發(fā)(重點(diǎn)了)

    最終繼承自EventDispatcher的對(duì)象都會(huì)含有dispatchEvent這個(gè)方法,他有一個(gè)參數(shù),事件對(duì)象。

    之前說到的事件注冊(cè)通道,他只是一個(gè)通道,實(shí)際上事件是由這個(gè)方法來分發(fā)出去的,通道只是一個(gè)管道而已。

    他的作用就是分發(fā)一個(gè)事件對(duì)象,他的分發(fā)是沒有目的的,一種廣播形式的,F(xiàn)lex的事件監(jiān)聽線程會(huì)接收到各種各樣的事件(我們稱之為捕獲事件,這在后面會(huì)介紹到),那么哪種才是你要的事件,標(biāo)識(shí)就通過事件的type屬性來區(qū)分。

    1)事件對(duì)象
    在分發(fā)事件時(shí),將會(huì)分發(fā)一個(gè)事件對(duì)象出去。不管是那個(gè)事件類,都是繼承自flash.events.Event對(duì)象的,他包含一些比較重要的屬性,type和bubbles。
    type是事件的類型,事件監(jiān)聽通過這個(gè)參數(shù)來識(shí)別是否是自己所監(jiān)聽的事件。
    bubbles是個(gè)布爾值,決定了該對(duì)象是否會(huì)向上傳遞。默認(rèn)是false。什么意思呢?畫個(gè)圖就明白了。
    比如說,當(dāng)button組件分發(fā)click事件對(duì)象時(shí),設(shè)置的bubbles為false,那么他的分發(fā)是這樣的

    示意代碼
    dispatchEvent(new MouseEvent( “click” , false ));

    事件對(duì)象無法跨越組件本身,當(dāng)然,除了之前講到的注冊(cè)通道(這樣就很形象了吧)

    因此,如果沒有注冊(cè)通道,在Flex主應(yīng)用中,就無法捕獲到這個(gè)button組件分發(fā)出的事件。

    如果我們將Bubbles設(shè)為true,他看起來就是這樣
    dispatchEvent(new MouseEvent( “click” , true ));


    可以看到,這個(gè)事件可以跨過組件本身,到達(dá)Flex主應(yīng)用里。不止這樣,在幫助手冊(cè)中明確說到,如果在傳遞過程中間一直沒有被捕獲的話,這個(gè)事件會(huì)逐層上傳,直到最終的stage,那時(shí)如果還沒被捕獲,這個(gè)事件就會(huì)被銷毀掉。

    這樣一來,即使我們沒有click的事件通道,只要我們?cè)贔lex主應(yīng)用中添加事件監(jiān)聽器(addEventListener)那么我們就可以獲得到這個(gè)分發(fā)出的click事件了。

    那么,注冊(cè)通道不是沒用了嗎?不是,之前說到過,注冊(cè)通道是現(xiàn)式的,可見的,因此如果你的組件要給其他人使用,那么就非常一目了然,而不必知道你源碼中究竟分發(fā)了什么事件。但是,不要監(jiān)聽和注冊(cè)同一個(gè)事件,這樣會(huì)重復(fù)執(zhí)行的。(后面將講到)

    5.      事件監(jiān)聽

    在分發(fā)中,我們講到,如果不是通過注冊(cè)通道來調(diào)用觸發(fā)事件,那么我們是需要一個(gè)監(jiān)聽來捕捉的。如何捕捉到分發(fā)出的事件,就是通過事件的type值。

    比如:
    <mx:Application xmlns:mx=http://www.adobe.com/2006/mxml layout="absolute" xmlns:comp
          creationComplete='init()'
    >
    <mx:Script>
                    <![CDATA[
    private function init(){
                        testBtn.addEventListener(“click”, clickHandler);
    }


    Flex的事件中都提供了一些靜態(tài)常量,讓我們調(diào)用,避免我們打錯(cuò)了。因此這句話可以這么寫

    testBtn.addEventListener(MouseEvent.CLICK,clickHandler);


    我們看到,監(jiān)聽的回調(diào)方法中沒有傳遞參數(shù),是的,這和通道的寫法有些不同,這里的回調(diào)方法(即clickHandler)只是個(gè)引用,并不是代表方法的執(zhí)行,他的含義是,告訴eventLinstener,如果捕捉到click事件,那么就去找clickHandler,并執(zhí)行它,event對(duì)象參數(shù)在執(zhí)行時(shí)動(dòng)態(tài)的傳遞。(如果熟悉ajax的朋友這里應(yīng)該很容易懂了)

    他作用起來就是這樣

    如果你又注冊(cè)了click的事件通道,那么這兩個(gè)都會(huì)生效,顯然這是多余的。

          6.  關(guān)于異步和執(zhí)行順序

    以前的說法有誤,as里是不存在線程概念的,在遠(yuǎn)程請(qǐng)求時(shí),結(jié)果事件、錯(cuò)誤事件都是異步的。如果你需要處理結(jié)果,需要利用監(jiān)聽,并在回調(diào)中獲取你的遠(yuǎn)程數(shù)據(jù)。
    而在處理本地事件時(shí),他們?nèi)匀皇峭降摹#ㄖx謝ltian 的指正)

    異步示意圖

    上圖可以看出,回調(diào)方法執(zhí)行的順序甚至還不如dispatchEvent之后的方法。如果接下來的方法依賴于事件回調(diào),那么把接下來的方法寫到回調(diào)方法中去


    三.綁定機(jī)制

          在我們了解了事件機(jī)制后,那么理解綁定就不難了。綁定其實(shí)也是事件機(jī)制的運(yùn)用

          1.  什么是綁定
    綁定的原理就是事件,在被綁定的對(duì)象上增加了改變事件的監(jiān)聽,一旦某個(gè)被綁定對(duì)象改變后,就會(huì)分發(fā)一個(gè)“propertyChange”事件(默認(rèn)的,也可以改變成自己定義的事件),在其他組件中,會(huì)有propertyChange的事件監(jiān)聽,當(dāng)捕捉到該事件后,則會(huì)去更新組件的屬性并顯示。

    綁定的作用在于,將Flex中的變量、類、方法等與組件的值進(jìn)行綁定。例如,一個(gè)變量如果被綁定后,那么引用該變量的組件的相關(guān)屬性也會(huì)發(fā)生改變。我們用一個(gè)實(shí)例來表示

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx=http://www.adobe.com/2006/mxml layout="absolute" xmlns:comp
          >
          <mx:Script>
              <![CDATA[
                    import mx.controls.Alert;           
                    [Bindable]
                    private var isSelected:Boolean;
                    private function clickHandler(e:MouseEvent){
                    //Alert.show(e.currentTarget.toString());
    isSelected=isSelected?false:true; //這句話的意思是如果isSelected為true,改變它為false,如果它為false,改變它為true;
                          Alert.show(isSelected.toString());
                    }
              ]]>
          </mx:Script>
          <mx:Button id="testBtn"  click="clickHandler(event)" label="測(cè)試" />
          <mx:CheckBox x="60" selected="{isSelected}" />
    </mx:Application>

    上述程序的效果就是,當(dāng)點(diǎn)擊button時(shí),button不是直接改變checkbox的選中狀態(tài),而是改變isSelected這個(gè)變量,由于isSelected是被綁定了的,那么會(huì)關(guān)聯(lián)的改變CheckBox的選中狀態(tài)。

    這樣看起來有些多此一舉,完全可以直接改變checkbox的selected屬性,我只是為了演示一下效果。如果說你的checkbox是動(dòng)態(tài)構(gòu)造的上百個(gè),你不會(huì)去一個(gè)個(gè)的改變他吧。

    因此,我們多數(shù)會(huì)將一個(gè)數(shù)據(jù)源進(jìn)行綁定聲明,這樣引用了這個(gè)數(shù)據(jù)源的控件,比如datagrid,在數(shù)據(jù)源發(fā)生了改變時(shí),即使你不重新設(shè)置dataProvider,列表的數(shù)據(jù)也會(huì)刷新。當(dāng)然,還有很多應(yīng)用等待你去嘗試。

    如果這個(gè)代碼中取消了[Bindable]的聲明,會(huì)怎么樣?isSelected不會(huì)改變了嗎?

    isSelected會(huì)改變,我們alert出來的結(jié)果也會(huì)顯示結(jié)果改變了,但是checkbox的選擇狀態(tài)不會(huì)改變,因?yàn)楫?dāng)一個(gè)組件由創(chuàng)建到最終顯示出來時(shí)是經(jīng)過很多方法的,比如addChild,commitProperties,updateDisplayList等,updataDisplayList則是類似刷新顯示效果一樣的方法。

    僅僅改變屬性,而不去更新顯示效果那么組件不會(huì)因?yàn)閷傩缘母淖兌l(fā)生任何變化。
     
    綁定的原理也是利用的事件分發(fā)。更復(fù)雜的綁定有待你去自己發(fā)現(xiàn)了



    四.  自定義事件的分發(fā)

          這部分就不長(zhǎng)篇大論了,因?yàn)楦魑粦?yīng)該已經(jīng)掌握了事件的原理,因此貼出演示源碼,并進(jìn)行些簡(jiǎn)單的解釋。

          1.  自定義事件 components/MyEventTest.as
          package components
    {
          import mx.events.FlexEvent;
          public class MyEventTest extends FlexEvent
          {
              public static const ONCHANGE:String = "onChange";
              public var eventInfo:String; //自定義的事件信息
              public function  MyEventTest(s:String){
                    super(s); //如果在構(gòu)造時(shí)不設(shè)bubbles,默認(rèn)是false,也就是不能傳遞的。
                    eventInfo="這個(gè)事件是:"+s;
              }
          }
    }

              2.        自定義組件 components/ComponentForEvent.as
    package components
    {
          import flash.events.EventDispatcher;
          //這個(gè)就是聲明事件注冊(cè)通道的方法了。name是事件對(duì)應(yīng)的名稱,也就是之前提到的type。Type是該事件的類
          [Event(name="onChange", type="components.MyEventTest")]
          public class ComponentForEvent extends EventDispatcher
          {
              private var name:String;
              public function changeName(newName:String){
                    this.name=newName;
                    dispatchEvent(new MyEventTest(MyEventTest.ONCHANGE) );
              }
          }
    }

    3.        App.mxml
    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:comp
    >
    <mx:Script>
    <![CDATA[
    import mx.controls.Alert;
    private function  changeName(){
                        cfe.changeName("新名稱");
    }
                    ]]>
    </mx:Script>
    <mx:Button id="testBtn"  click=" changeName ()" label="測(cè)試" />
    <components:ComponentForEvent
    id="cfe"  />
    </mx:Application>
    posted on 2008-08-26 18:26 kissjava 閱讀(12415) 評(píng)論(2)  編輯  收藏 所屬分類: Flex

    評(píng)論

    # re: Flex事件講解【轉(zhuǎn)】 2011-04-28 22:56 布拉德比特
    樓主啊,關(guān)于bubble設(shè)置為false和true的那兩張圖有區(qū)別么?  回復(fù)  更多評(píng)論
      

    # re: Flex事件講解【轉(zhuǎn)】[未登錄] 2012-12-26 16:36 harvey
    是的 bubble設(shè)置為false和true的那兩張圖貌似沒有區(qū)別,不過對(duì)于事件講的還是清晰,受益匪淺,自己對(duì)于異步的處理還是要多研究。 謝謝樓主了  回復(fù)  更多評(píng)論
      

    主站蜘蛛池模板: 亚洲精品无码久久毛片| 国产亚洲sss在线播放| 青青青免费国产在线视频小草| 亚洲w码欧洲s码免费| 青青青国产色视频在线观看国产亚洲欧洲国产综合 | 久99久精品免费视频热77| 亚洲视频一区在线播放| 国产精品二区三区免费播放心| 丝袜足液精子免费视频| 亚洲日本成本人观看| 亚洲av中文无码乱人伦在线r▽| 在线观看av永久免费| 国产成年无码久久久免费| 一区二区亚洲精品精华液 | 亚洲人成人77777网站不卡| 亚洲免费日韩无码系列| 中文字幕无码不卡免费视频| 国产成人无码免费看片软件| 国产成人亚洲综合一区| 亚洲av无码一区二区三区网站| 免费国产在线观看老王影院| 四虎精品视频在线永久免费观看| 国产精品免费大片一区二区| 一区二区亚洲精品精华液| 亚洲人成亚洲精品| 激情综合色五月丁香六月亚洲| 日韩中文字幕在线免费观看 | 亚州免费一级毛片| 99re6在线精品免费观看| 亚洲国产成人无码AV在线影院| 亚洲午夜未满十八勿入| 久久久久亚洲AV无码专区桃色| 四虎成人免费网站在线| xxxx日本免费| 亚洲a一级免费视频| 一区二区视频免费观看| 美女裸免费观看网站| 亚洲人成色777777精品| 激情五月亚洲色图| 亚洲制服在线观看| 亚洲精品在线免费看|