雖然多數Flex開發者都使用過[Bindable]标簽,但是很多人都不知道這個标簽的作用甚至不知道該标簽為何物。[Bindable]就是所謂的中繼資料标簽。中繼資料标簽是一種特殊的标簽,它在代碼中的作用就是向編譯器提供如何編譯程式的資訊。實際上,這些标簽并沒有被編譯到生成的SWF檔案中,而隻是告訴編譯器如何生成SWF檔案。文檔中列出的中繼資料标簽共有12個,本文将講解這些中繼資料标簽的定義并給出使用它們的示例,在看完這篇文章之後,你就會明白應該在何時何處在你的Flex 2應用程式中使用中繼資料标簽了。
[ArrayElementType]
實際上,定義一個數組通常來說是一件很平常的事情,因為數組中的元素可以是任何類型的。不過,使用ArrayElementType中繼資料标簽可以讓你定義數組元素的資料類型。下面的例子展示了如何使用[ArrayElementType]:
程式代碼
Java代碼
- [ArrayElementType("String")]
- public var arrayOfStrings:Array;
- [ArrayElementType("Number")]
- public var arrayOfNumbers:Array;
- [ArrayElementType("mx.core.UIComponent")]
- public var arrayOfUIComponents:Array;
[Bindable]
什麼是中繼資料(metadata):[Bindable]大概又是Flex用得最多的中繼資料了。我就按自己的了解随便解釋一下:首先要明白中繼資料不是文法的一部分,而是專門給編譯器用的,說白了是告訴編譯器做某些事情,學過java之類的應該知道。那Bindable來講,它的作用是告訴 flex編譯器,給某些某些東西建立綁定關系,flex編譯器會在編譯過程中給AS(flex編譯器就是把mxml編譯成as,再編譯到swf,也可能直接編譯倒swf,我這裡假設有as這麼個環節)加一點事件發生和處理之類的代碼,由此綁定的關系便建立了,如果我們用純粹as3代碼來寫也是可以實作的,就是太太太麻煩。
什麼是綁定:
舉個例子:給下面的public變量加上[Bindable]
- public var name:String = "";
作為一個public變量,肯定既可以被指派,也能指派給别的變量。綁定的作用就是,當name改變的時候(被指派了),可能通知其它被name影響(指派給它們)的變量發生改變。這裡的“可能”就需要編譯器來判斷,這就是為什麼中繼資料是給編譯器用的原因了。在mxml裡用{}的文法的地方就是綁定的對象,比如label={xxx.name},當name變化,label也跟着變化。這樣,我們隻是很簡單的改變了name的值,由于有綁定,界面上的 label也跟着自動變化了,爽吧。
能用在哪裡
三個地方:類, 變量, getter/setter。是不是public沒有關系,private的就隻能給自家用呗。用在Class上就是簡單的給所有的public屬性(包括變量,getter/setter,普通方法)加上 [Bindable],可是一般的方法不能用[Bindable]呀,于是一般就能看到flex給了個warning,直接無視:)。變量嘛就是上面講的,很簡單略掉。
用在隻讀,隻寫屬性(getter/setter)上面
終于講到關鍵地方了,因為getter和setter很像方法,用起來會有點不同。看看這個例子:
- private var content:Array = new Array();
- public function set _content(ct:String):void
- {
- content = ct.split(SEP);
- }
- 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;
原來的設想是content綁定_wholeText,可它是不工作的。為什麼?_wholeText太複雜了,被編譯器排除在“可能”之外,編譯器認為沒有綁定關系,如果隻是簡單的return content,倒是可以的。我這裡搜到了一些比較權威的解釋。來自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.
說白了就是為了降低複雜度和提高效率,複雜情況的getter會被忽略。如何解決?可以手動建立綁定,即[Bindable("eventName")]。把代碼改成這樣:
- this.dispatchEvent(new Event("_contectChanged"));
- [Bindable("_contectChanged")]
這樣就避免了編譯器去自動識别。自己加上綁定關系,當_content被指派,發出_contentChanged事件,通知所有被綁定的getter方法執行一遍。這也說明了,綁定不過是事件遊戲而已,flex為使用者隐藏了很多底層算法。
[DefaultProperty]
DefaultProperty中繼資料标簽用來将一個單一屬性設定為某個類的預設屬性。它允許在一個容器标簽内設定屬性,而不用定義屬性的名字。一個簡單的例子就是一個自定義Button類。Listing 3展示了一個簡單的Button類,它将label屬性設定為了DefaultProperty。
46
Listing 4展示了label屬性是如何在自定義Button标簽中作為一個字元串定義的。
[Embed]
Embed中繼資料标簽用來導入圖檔到程式。可以通過兩種方式使用Embed。你可以将圖檔嵌入到ActionScript中并将其指派給一個變量(如同下面代碼中的第一個例子),或者你也可以将圖檔直接指派給元件的屬性(使用下面代碼中的第二個例子所示的文法規則)。
例1:
[Embed(source="myIcon.gif")]
[Bindable]
public var myIcon:Class;
例2:
上面這兩個例子産生的結果是一樣的。建立myIcon類的好處是,它在一個類中隻定義一次并可以綁定到程式中的多個元件。
[Event]
Event中繼資料标簽用來聲明那些被自定義類分派的事件。将這個中繼資料标簽添加到類定義中之後,你就可以在MXML标簽中添加事件處理函數來初始化該自定義類。Listing 5建立了一個自定義Button類,每當它的label屬性改變的時候就會分派一個事件。Listing 6所顯示的主程式檔案初始化了這個自定義Button并建立了事件處理函數,該函數将新的labe屬性值賦給了一個TextArea元件以顯示目前發生的更改。
圖4顯示了Listing 5 和 Listing 6中的代碼運作結果。
圖4:
[Effect]
Effect中繼資料标簽用來定義一個自定義效果,當某個事件發生的時候該效果會被分派。這個示例可以基于前面Event的例子來建立,通過簡單地更改ButtonLabel類(Listing 7)中的一行代碼,就定義了一個效果,該效果可以在MXML标簽中直接使用(Listing。
[IconFile]
IconFile是用來定義一個jpg,gif或者png檔案的檔案名的,它在你的自定義類中作為圖示來使用。[Embed]中繼資料标簽可以用來嵌入圖檔、SWF檔案、音樂檔案以及視訊檔案等,而IconFile則隻是用來嵌入用來作為自定義類圖示的檔案。下面是一個IconFile的例子:
[IconFile("icon.png")]
public class CustomButton extends Button
{
}
[Inspectable]
在使用Flex Builder 2的時候,你可能會希望某些自定義元件的屬性在代碼提示和屬性檢查器(property inspector)中顯示,Inspectable中繼資料标簽就是用來定義那些屬性的。Listing 9展示的例子定義了一個inspectable的ccType變量,它定義了Visa為預設值、Credit Card為類别并将取值範圍定義為包含了Visa, Mastercard, Discover, 和 American Express的枚舉。
圖5展示了當将元件添加到程式中的時候所顯示的代碼提示。
圖5:
圖6與上面展示的是同樣的代碼,但是這次是設計視圖,是以我們能看到屬性檢查器。你可以看到屬性ccType的類别為Credit Card,它的所有可選的值都在下拉清單中。
圖6:
[InstanceType]
當在一個模闆對象中聲明一個像IDeferredInstance這樣的變量時,InstanceType中繼資料标簽就用來聲明對象的類型。下面是InstanceType的用法:
[InstanceType("package.className")]
[NonCommittingChangeEvent]
NonCommittingChangeEvent中繼資料标簽在某個特定事件發生的時候可以防止變量在事件發生的過程中被更改。Listing 10展示了它是如何工作的。一個名為s的字元串類型的私有變量被綁定到了名為ti2的TextInput元件上。另外一個id為ti1的TextInput元件在它的text發生更改的時候就會将s的值設定為它的text屬性的值。另外,當triggerBinding 事件被分派的時候,附加在s變量上的Binding中繼資料标簽就會進行綁定。隻有在Enter鍵在ti1 TextInput元件中被按下時才會分派triggerBinding事件。
[RemoteClass]
RemoteClass可以用來将一個ActionScript類綁定到一個Java類或一個ColdFusion CFC。這樣做可以自動轉換資料類型。下面的例子将包com.mydomain中的名為MyClass的ActionScript類綁定到了同一個包中名為MyClass的Java類:
package com.mydomain {
[Bindable]
[RemoteClass(alias="com.mydomain.MyClass")]
public class MyClass {
public var id:int;
public var myText:String;
}
[Style]
Style中繼資料标簽用來為元件定義自定義樣式屬性的。隻需要簡單地将Sytle中繼資料标簽添加到類的定義當然,然後就可以使用getSytle方法擷取它的值了。Listing 11 和 12中的例子定義了兩個樣式,分别為borderColor 和fillColor,它們的資料類型都是uint。當類初始化的時候這兩個樣式就會在标簽中被設定。代碼中覆寫了updateDisplayList函數,用自定義的樣式畫了一個圓形邊框并将其填充。
圖7展示了Listing 11 和 Listing 12中代碼運作的結果。
圖7:
現在你應該會有這樣的感覺了:“喔,現在我知道在哪裡可以使用它們了”或者“嗯,我想我會在新的項目中嘗試使用這些中繼資料标簽”。如果你沒有,那麼你可能需要回過頭去再看一遍這篇文章。OK,我想說的是Adobe Flex小組提供給我們的中繼資料标簽不隻是非常的強大,可以讓我們擴充或自定義我們要做的東西,而且它還非常易于使用。通過使用它們,僅僅幾行代碼就可以完成一大堆事情。如果不使用這些标簽,你會發現在Flex 2中實作一些東西是很辛苦的。
此資訊來自〖閃無憂〗
檢視原網址:http://www.5uflash.com/Html/flex/091053329_3.html