Flex 4 SDK – MXML 2009

Flex 3的命名空間

Flex 3定義了唯一的MXML命名空間,即MXML 2006。在Flex Builder 3中聲明MXML 2006命名空間的默認格式如下:

xmlns:mx="http://www.adobe.com/2006/mxml"

值得注意的是,很多初學者誤認爲”mx”爲命名空間。事實上,上面的語句中”mx”只是命名空間的前綴,或者說是一個“別名”。你可以將mx修改爲任意值,甚至可以使用“空前綴”,例如:

<Application xmlns="http://www.adobe.com/2006/mxml"> <Button /> </Application>

MXML 2009

如果你使用Flash Builder 4創建一個Flex 4應用程序,會發現默認情況下FB爲你創建了3個命名空間,如下所示:

<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/halo" .... </s:Application>

情況似乎複雜了?爲了更好的理解Flex 4中的命名空間,首先需要介紹兩個名詞:“語言級命名空間”和“組件級命名空間”。

語言級命名空間

語言級命名空間聲明瞭一個MXML文件所使用的語言版本,上面實例中,
http://ns.adobe.com/mxml/2009即爲語言級命名空間,表示當前MXML文件使用的語言版本爲MXML 2009。語言級命名空間具有如下特點:

  • 每個MXML文件必須聲明且只能聲明一個語言級命名空間,Flex編譯器根據這個命名空間來確定以何種方式編譯該MXML。
  • 在一個應用程序中的多個MXML文件可以使用不同的命名空間(MXML 2006或MXML 2009)。

除了聲明語言版本外,語言級命名空間還定義了一組標籤,如<Script>,<Style>等等。這些標籤可以理解爲MXML的“關鍵字”。在MXML 2009中保留了MXML 2006的全部語言級標籤,並增加了一些新的標籤,以下是完整的列表:(粗體爲Flex 4新增標籤,我們將在下一章中具體介紹)

  • <fx:Binding>
  • <fx:Component>
  • <fx:Metadata>
  • <fx:Model>
  • <fx:Script>
  • <fx:Style>
  • <fx:Declarations>
  • <fx:Library>
  • <fx:Definition>
  • <fx:Private>
  • <fx:Reparent>
  • <fx:DesignLayer>

另一方面,語言級命名空間還定義了ActionScript3中的基礎數據類型的映射:

  • <fx:Array>
  • <fx:Boolean>
  • <fx:Class>
  • <fx:Date>
  • <fx:Function>
  • <fx:int>
  • <fx:Number>
  • <fx:Object>
  • <fx:RegExp>
  • <fx:String>
  • <fx:uint>
  • <fx:Vector>
  • <fx:XML>
  • <fx:XMLList>

組件級命名空間

顧名思義,組件級命名空間定義了組件標籤的集合,每一個組件標籤都與一個ActionScript類或MXML文件相對應。在Flex 4中共定義了兩個組件命名空間,分別是:
Spark組件空間(”library:ns.adobe.com/flex/spark“,默認別名爲“s”)
Halo組件空間(“library:ns.adobe.com/flex/halo”,默認別名爲”mx”)

之所以需要兩個命名空間主要是爲了迴避組件命名上的衝突問題。事實上,在Flex 4的早期的構建中,所有Spark組件類均以Fx作爲前綴以和Halo組件區別,例如Spark中的Application組件被命名爲FxApplication,Button組件被命名爲FxButton,以此類推。但最終Flex SDK的開發團隊放棄了這種古怪的命名方式,而改爲使用不同的命名空間。

例1:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
<?xml version="1.0" encoding="utf-8"?> <s:Applicationxmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"xmlns:mx="library://ns.adobe.com/flex/halo"> <fx:Script> <![CDATA[ protected function sparkButton_onClick(event:MouseEvent):void { haloButton.label = "Flex 4 Rocks!";	} ]]></fx:Script>   <s:Button id="sparkButton" label="Spark Button"click="sparkButton_onClick(event)" /> <mx:Button id="haloButton" label="Halo Button"y="30" /> </s:Application>

例1可以算是Flex 4的Hello,world程序,非常簡單。它分別創建了一個Spark Button組件和一個Halo Button組件,並在點擊Spark Button時將Halo Button的label設置爲“Flex 4 Rocks!”。

Flex組件到MXML標籤的映射

前面曾經提到過,每一個MXML組件標籤都對應着一個ActionScript類或者MXML文件類。那麼,Flex是如何建立起這種映射關係的呢?
其實原理並不複雜,這種映射關係主要是通過一個清單文件(Manifest.xml)來定義,一個典型的清單文件如下:

<?xml version="1.0"?> <componentPackage> <component id="Accordion"class="mx.containers.Accordion"/> <component id="AddChild" class="mx.states.AddChild"/><component id="AddChildAction" class="mx.effects.AddChildAction"/> .... </componentPackage>

Flex SDK在編譯時,會向編譯器提供清單文件和相對應的命名空間,如library://ns.adobe.com/flex/halo。編譯後的Flex框架中,就包含了那些MXML標籤與實際類定義的映射關係了,如下圖所示:

注意:多個清單文件可以使用相同的命名空間編譯,同一個類定義也可以出現在多個清單文件中,例如,對於HTTPService組件,你可以使用Halo組件空間來引用(<mx:HTTPService />),也可以使用Spark組件空間(<s:HTTPService />)來引用。

由於Flex框架本身被分爲若干個工程(Halo, Spark, RPC, AIR-framework, TextLayout等等),所以每個工程下面也都有各自定義清單文件,可以在下面目錄找到(這裏僅列出兩個):
For Halo: {SDK_ROOT}/frameworks/projects/frameworks/manifest.xml
For Spark: {SDK_ROOT}/frameworks/projects/spark/manifest.xml

值得注意的是,Flex框架組件映射的方法也可以爲一般開發者所使用,可以爲你自己的類庫創建這種URI風格的命名空間。使用URI而不是包結構類型的命名空間的一大好處是,在MXML中引用的標籤可以做與實際類所在的包結構無關,即使未來某個類由於重構,其所在的包的目錄結構變化了,引用改類的MXML也絲毫不會受到影響。
具體如何創建URI風格的命名空間.

介紹 了MXML 2009新增的標籤,包括:

  • Declarations
  • Vector
  • Library
  • Definition
  • Private
  • Reparent

<Declarations />

Declarations標籤是Flex 4中最常用的新增標籤。

在Flex 3中,對於一個MXML組件的直接子元素,可以有以下幾種情況:

1. 屬性標籤,例如:

<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml" > 
<mx:text > 
<mx:String > test</mx:String > 
</mx:text > 
</mx:Label >

2. 作爲默認屬性的值,例如: 

List的默認屬性爲DataProvider

<mx:List xmlns:mx="http://www.adobe.com/2006/mxml" > 
<mx:ArrayCollection > 
....
</mx:ArrayCollection > 
</mx:List >

 

3. 作爲容器的Children:

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" > 
<mx:Button /> 
<mx:Label /> 
</mx:Canvas >

4. 聲明並創建非可視化對象:

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" > 
<mx:HTTPService id="sevice" /> 
</mx:Canvas >

在Flex 4中,對於MXML組件的直接子元素有着更加規範的定義,即:所有直接子元素或者是組件的屬性標籤,或者是作爲組件默認屬性的值而存在。 而 容器的默認屬性即爲其Children的集合(例如Group的默認屬性爲mxmlContent,DataGroup的默認屬性爲 dataProvider)。

 

而對於最後一種情況,在Flex 4中,在MXML中創建非可視化對象,如HTTPService, Effect, 基本數據類型等等,必需通過<Declarations/>標籤來完成。例如聲明一個HTTPService對象:

<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library:ns.adobe.com/flex/spark" > 
<fx:Declarations > 
<s:HTTPService id="service" /> 
</fx:Declarations > 
</s:Group >

上面的代碼等價於ActionScript:

public MyGroup extends Group { 
private var service: HTTPService = new HTTPService( ) ;
}

值得注意的是,Declarations標籤也可以用來聲明、創建任何可視化組件 ,但是使用該標籤創建的組件不 會被加入到DisplayList中,也不會被初始化。你可以在需要的時候再使用它。

<Vector />

Vector是Flash Player 10中新增加的數據類型(結構),大多數情況下,使用Vector比使用Array更加高效。在Flex 4中,你可以通過MXML來創建一個Vector對象,例如:

<fx:Declarations > 
<fx:Vector id="myVector" type="String" fixed="false" /> 
</fx:Declarations >

上述代碼相當於ActionScript:

public var myVector: Vector.< String> = new Vector.< String> ( 0 ,false ) ;

<Library />和<Definition />

Library標籤允許你爲當前的MXML組件聲明一個”類庫“。相應地,Definition標籤可以定義該類庫中的一個”類”。基本的語法規則 如下:

 

  • 如果使用Library標籤,則它必須是MXML或FXG文檔中的第一個標籤。
  • Library標籤可以包含一個或多個Definition標籤。
  • 必須爲Definition標籤提供name屬性作爲”類名”,同時Definition標籤必須有且只能有一個直接子標籤作爲其所定義的類的基 類。
  • 使用Definition標籤定義的類也可以使用<fx:Script />和<fx:MetaData />標籤。
  • 由Definition標籤定義的類屬於默認包,需使用MXML 2009的命名空間來引用。如類名爲MyClass,則在MXML中使用該類的標籤爲<fx:MyClass/>。
  • Library和Definition標籤不可嵌套使用,即在由Definition定義的類中,不能使用Library和Definition 標籤。

下面的代碼中,使用Library和Definition標籤創建了MyClass類及其子類MySubClass:

<!-- MyApp.mxml --> 
<s:Applicaiton xmlns:fx=... > 
<fx:Library > 
<!-- 此處定義了一個名爲MyClass的類,繼承自Group類 --> 
<fx:Definition name="MyClass" > 
<s:Group > 
<s:Rect width="200" height="200" > 
<s:fill .../> 
</s:Rect > 
</s:Group > 
</fx:Definition > 
<!-- 此處定義了一個名爲MySubClass的類,繼承自MyClass類> 
<fx:Definiton name="MySubClass" > 
<fx:MyClass /> 
</fx:Definition > 
</fx:Library > 
 
<!-- 使用MyClass和MySubClass類 --> 
<fx:MyClass /> 
<fx:MySubClass /> 
</s:Application >

此外,由Definition定義的類的實例,不能賦予id屬性(例如,在上面代碼中,如果爲MyClass實例聲明id屬性會造成編譯錯誤)。這 本質上是由Library的“私有性”決定的。在大多數情況下,該標籤會在FXG中使用,用於定義可重用的圖形元素。

 

小技巧 

事實上,儘管不能爲Definition定義的類的實例賦予id屬性,我們仍然可以獲取這些類的 實例的引用,通過查看Flex編譯後的AS代碼(使用-keep參數)可以發現:所有由Definition定義的類最終會被轉化爲類名 爲”MXML類名_definitionN.as”這樣的獨立ActionScript類 。

例如,上面例子(MXML類名爲 MyApp)中的MyClass和MySubClass最終會被轉化爲MyApp_definition1和MyApp_definition2。在確定 這些類的實際類名後,我們可以通過一些系統事件來獲取這些類的引用並對其進行操作,例如:

<!-- Test.mxml --> 
<?xml version="1.0" encoding="utf-8" ?> 
<s:Application xmlns:fx="..." xmlns:s="..." > 
<fx:Library > 
<fx:Definition name="MyRect" > 
<s:Group width="100" height="100" > 
....
</s:Group > 
</fx:Definition > 
</fx:Library > 
 
<fx:MyRect creationComplete="myrect1_creationComplete(event)" /> 
 
<fx:Script > 
<![ CDATA[ 
import mx.events.FlexEvent; 
private var myRect:Test_definition1 ; 
 
<!-- 通過事件獲取實例的引用 --> 
protected function myrect1_creationComplete(event:FlexEvent):void
{
myRect = event.target as Test_definition1;
myRect.x = 200;
}
]]>
</fx:Script > 
</s:Application >

<Private />

Private標籤用於提供MXML和FXG文檔的元信息,標籤內的內容會被編譯器忽略。儘管如此,你必須保證其內容是有效的XML格式。例如:

<fx:Private > 
<Author> Jinni Cao</Author> 
<Version> 1.0</Version> 
<Site> http://www.SWFever.com</Site> 
</fx:Private >

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