丄諦啲仇魜ヤ
          如 果 敵 人 讓 你 生 氣 , 那 說 明 你 沒 有 勝 他 的 把 握!
          posts - 6,comments - 56,trackbacks - 1

          [Bindable]大概又是Flex用得最多的元數(shù)據(jù)了。剛開始用用確實(shí)好簡單,效率真是沒的說。不過這幾天用著卻碰到了些問題,我自己搜集了些資料,想著有必要在blog里總結(jié)一下吧。

          啥是元數(shù)據(jù)(metadata)

          知道就跳過吧。今天不曉得為什么livedoc.adobe.com這么慢,沒辦法,拿不到權(quán)威的解釋了。我就按自己的理解隨便解釋一下:首先要明白元數(shù)據(jù)不是語法的一部分,而是專門給編譯器用的,說白了是告訴編譯器做某些事情,學(xué)過java之類的應(yīng)該知道。那Bindable來講,它的作用是告訴flex編譯器,給某些某些東西建立綁定關(guān)系,flex編譯器會在編譯過程中給AS(flex編譯器就是把mxml編譯成as,再編譯到swf,也可能直接編譯倒swf,我這里假設(shè)有as這么個環(huán)節(jié))加一點(diǎn)事件發(fā)生和處理之類的代碼,由此綁定的關(guān)系便建立了,如果我們用純粹as3代碼來寫也是可以實(shí)現(xiàn)的,就是太太太麻煩。

          啥是綁定

          知道繼續(xù)跳過。舉個例子:給下面的public變量加上[Bindable]

          [Bindable]
          public var name:String = "";

          作為一個public變量,肯定既可以被賦值,也能賦值給別的變量。綁定的作用就是,當(dāng)name改變的時候(被賦值了),可能通知其它被name影響(賦值給它們)的變量發(fā)生改變。這里的“可能”就需要編譯器來判斷,這就是為什么元數(shù)據(jù)是給編譯器用的原因了。在mxml里用{}的語法的地方就是綁定的對象,比如label={xxx.name},當(dāng)name變化,label也跟著變化。這樣,我們只是很簡單的改變了name的值,由于有綁定,界面上的label也跟著自動變化了,爽吧。

          能用在哪里

          三個地方:類, 變量, getter/setter。是不是public沒有關(guān)系,private的就只能給自家用唄。用在Class上就是簡單的給所有的public屬性(包括變量,getter/setter,普通方法)加上[Bindable],可是一般的方法不能用[Bindable]呀,于是一般就能看到flex給了個warning,直接無視:)。變量嘛就是上面講的,很簡單略掉。

          用在只讀,只寫屬性(getter/setter)上面

          終于講到關(guān)鍵地方了,因?yàn)間etter和setter很像方法,用起來會有點(diǎn)不同。看看這個例子:

          [Bindable]
          private var content:Array = new Array();
          [Bindable]
          public function set _content(ct:String):void
          {
          content = ct.split(SEP);
          }
          [Bindable]
          public function get _wholeText():String
          {
          if(content.length == 0)
          {
          return "";
          }
          else
          {
          var _w:String = "";
          for(var i:int=0 ; i<content.length ; i++)
          {
          _w += content[i] + "\r\n";
          }
          return _w;
          }
          }

          原來的設(shè)想是content綁定_wholeText,可它是不工作的。為什么?_wholeText太復(fù)雜了,被編譯器排除在“可能”之外,編譯器認(rèn)為沒有綁定關(guān)系,如果只是簡單的return content,倒是可以的。我這里搜到了一些比較權(quán)威的解釋。來自http://www.rubenswieringa.com/blog/binding-read-only-accessors-in-flex找到Ely Greenfield講的。

          Now keep in mind that there’s no way for the compiler to actually tell if the value of a property get function would be different if called, short of doing an extensive code flow analysis of the get function, identifying all the inputs that might be affecting the value of the get function (i.e., member fields, statics, globals that are used in the get function and in any methods, global functions, closures, etc) it might call, and setting up watchers on every one of those to trigger the binding when any of them change. That’s prohibitively difficult, and expensive to do. So the compiler doesn’t try.

          Instead when you put [Bindable] on a get/set property, the compiler makes it bindable with a little creative rewriting that allows the framework to watch the get function, and dispatch a change event when the get function is triggered. This means that automatic bindable properties don’t work when the get function is computed from multiple values, or when you change its value by setting a backing field, rather than using the set function.

          It _also_ means that if you have no set function, we can pretty much guarantee that there’s no way automatically bindable get properties will be triggered. a read only propeerty is, to the compiler, completely opaque…at the moment, it has no idea where that value is coming from, and hence will never be able to ‘automatically’ trigger the binding.

          說白了就是為了降低復(fù)雜度和提高效率,復(fù)雜情況的getter會被忽略。如何解決?可以手動建立綁定,即[Bindable("eventName")]。把代碼改成這樣:

          [Bindable]
          private var content:Array = new Array();
          [Bindable]
          public function set _content(ct:String):void
          {
          content = ct.split(SEP);
          this.dispatchEvent(new Event("_contectChanged"));
          }
          [Bindable("_contectChanged")]
          public function get _wholeText():String
          {
          if(content.length == 0)
          {
          return "";
          }
          else
          {
          var _w:String = "";
          for(var i:int=0 ; i<content.length ; i++)
          {
          _w += content[i] + "\r\n";
          }
          return _w;
          }
          }

          這樣就避免了編譯器去自動識別。自己加上綁定關(guān)系,當(dāng)_content被賦值,發(fā)出_contentChanged事件,通知所有被綁定的getter方法執(zhí)行一遍。這也說明了,綁定不過是事件游戲而已,flex為用戶隱藏了很多底層算法。

          posted on 2009-04-13 17:08 Crying 閱讀(267) 評論(0)  編輯  收藏 所屬分類: FLEX
          主站蜘蛛池模板: 泗阳县| 德格县| 山西省| 保靖县| 栾川县| 鄯善县| 内黄县| 延长县| 拜泉县| 蓬安县| 惠州市| 达孜县| 金昌市| 高要市| 海伦市| 宜兴市| 黄浦区| 陈巴尔虎旗| 密山市| 密云县| 永德县| 平原县| 玉山县| 定西市| 当阳市| 武川县| 和平县| 阳高县| 望谟县| 克什克腾旗| 潞西市| 永济市| 九江市| 新竹县| 沾化县| 东明县| 南阳市| 铜鼓县| 四会市| 新郑市| 桦川县|