现在的位置: 首页 > 综合 > 正文

Flex 4 SDK – MXML 2009

2013年03月10日 ⁄ 综合 ⁄ 共 7161字 ⁄ 字号 评论关闭

http://blog.csdn.net/sysu_2010/article/details/6614697

 

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:

<?xml version="1.0" encoding="utf-8"?>
<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">
	<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"?>

<!--

    MX Components

-->
<componentPackage>

    <!-- mx -->
    <component id="Accordion" class="mx.containers.Accordion"/>
    <component id="AddChildAction" class="mx.effects.AddChildAction"/>
    <component id="AddItemAction" class="mx.effects.AddItemAction"/>
    <component id="Application" class="mx.core.Application"/>
    <component id="ApplicationControlBar" class="mx.containers.ApplicationControlBar"/>
    <component id="Box" class="mx.containers.Box"/>
    <component id="Button" class="mx.controls.Button"/>
    <component id="ButtonBar" class="mx.controls.ButtonBar"/>
    <component id="Canvas" class="mx.containers.Canvas"/>

    ...
</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 >

抱歉!评论已关闭.