MXML 语法
MXML 是Adobe Flex™应用中一种用于展示用户界面组件的XML 语言。
大多数MXML标签相当于ActionScript 3.0的类或者类属性。Flex解析MXML标签,并将其编译成一个包含对应ActionScript对象的SWF文件。
ActionScript 3.0 使用的语法基于 ECMAScript语言规范草案(第4版)。ActionScript 3.0 包含下列特性:
关于ActionScript 3.0的更多信息,参见 Using ActionScript。
MXML文件名必须遵守下列命名约定:
对应于ActionScript类的MXML标签采用的命名约定和ActionScript类相同。 类名以大写字母开头,大写字母区分类名中的单词。比如,当一个标签对应一个ActionScript类时,它的属性对应于该类的属性和事件。
MXML中组件属性使用的命名约定和对应的ActionScript属性相同。属性名以小写字母开头,大写字母区分属性名中的单词。
大多数组件属性设置和标签属性一样,形式如下:
<mx:Label width="50" height="25" text="Hello World"/>
所有组件属性可以设置为子标签,形式如下:
<mx:Label>
<mx:width>50</mx:width>
<mx:height>25</mx:height>
<mx:text>Hello World</mx:text>
</mx:Label>
当设置属性值为一个复杂的Object时,通常可以使用子标签,因为不能指定一个复杂的Object作为标签属性值。在下面的例子中,使用子标签将ComboBox控件的dataProvider设置为一个ArrayCollection对象:
<mx:ComboBox>
<mx:dataProvider>
<mx:ArrayCollection>
<mx:String>AK</mx:String>
<mx:String>AL</mx:String>
<mx:String>AR</mx:String>
</mx:ArrayCollection>
<mx:dataProvider>
</mx:ComboBox>
在前面例子中,使用子标签设置属性的一个限制是子标签命名空间前缀mx:必须匹配组件标签的命名空间前缀。
每一种组件属性均是以下类型之一:
Adobe建议你使用标签属性赋标量值,而使用子标签赋一些复杂的类型,比如ActionScript对象。
通常指定标量属性值作为组件标签的属性,如下所示:
<mx:Label width="50" height="25" text="Hello World"/>
很多组件属性的有效值由静态常量定义,这些静态常量在ActionScript类中定义。MXML中可以使用静态常量设置属性值,也可以使用静态常量值,如下所示:
<!-- 使用静态常量设置属性。 -->
<mx:HBox width="200" horizontalScrollPolicy="{ScrollPolicy.OFF}">
...
</mx:HBox>
<!—使用静态常量值设置属性。 -->
<mx:HBox width="200" horizontalScrollPolicy="off">
...
</mx:HBox>
HBox容器定义了horizontalScrollPolicy属性,用于定义容器水平滚动条的操作。本例中,你显式设置horizontalScrollPolicy属性,禁用了水平滚动条。
第一个例子中使用ScrollPolicy类定义的静态常量OFF设置horizontalScrollPolicy属性。在MXML中,设置属性值为静态常量时必须使用数据绑定语法。使用静态常量的好处是Flex编译器能识别不正确的属性值,在编译期会报错。
不过,你也设置horizontalScrollPolicy属性值为静态常量的值。静态常量OFF 的值为“off”。当你使用静态常量值设置属性值时,Flex编译器不能确定是否使用了一个不支持的值。如果你设置属性不正确,直到报运行时错误才会知道。
在ActionScript中,应当总是使用静态常量设置属性值,如下所示:
var myHBox:HBox = new HBox();
myHBox.horizontalScrollPolicy=ScrollPolicy.OFF;
很多Flex组件定义了一个默认属性。default_property是MXML标签属性,如果你不明确指定该属性,则默认为MXML标签内的内容。比如,考虑以下MXML标签定义:
<mx:SomeTag>
anything here
</mx:SomeTag>
如果该标签定义了默认属性default_property,那么前面的标签定义相当于如下代码:
<mx:SomeTag>
<default_property>
anything here
</default_property>
</mx:SomeTag>
也相当于以下代码:
<mx:SomeTag default_property="anything here"/>
默认属性为设置单个属性提供了一种简写机制。比如ComboBox,默认属性是dataProvider。因此,下列代码中两个ComboBox的定义是等价的:
<?xml version="1.0"?>
<!-- mxml/DefProp.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >
<!-- 省略默认属性。 -->
<mx:ComboBox>
<mx:ArrayCollection>
<mx:String>AK</mx:String>
<mx:String>AL</mx:String>
<mx:String>AR</mx:String>
</mx:ArrayCollection>
</mx:ComboBox>
<!-- 明确指定默认属性。 -->
<mx:ComboBox>
<mx:dataProvider>
<mx:ArrayCollection>
<mx:String>AK</mx:String>
<mx:String>AL</mx:String>
<mx:String>AR</mx:String>
</mx:ArrayCollection>
</mx:dataProvider>
</mx:ComboBox>
</mx:Application>
不是所有Flex组件都定义有默认属性。要确定每一个组件的默认属性,参见《Adobe Flex Language Reference》。
创建一个自定义组件时也可以定义默认属性。更多信息,参见《Creating and Extending Adobe Flex 3 Components》中的“自定义组件的原数据标签”。
在MXML中设置属性值时,可以以反斜杠字符(/)作为前缀对保留字进行转义,如下所示:
<?xml version="1.0"?>
<!-- mxml/EscapeChar.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >
<mx:Label text="/{/}"/>
</mx:Application>
本例中,你想在文本字符串中使用大括号({ })。但是Flex使用大括号表示数据绑定操作。因此,你应在每一个大括号前加反斜杠(/)使得MXML编译器将它们解释为字面意义。
当MXML 中String类型的属性值含反斜杠时,MXML编译器会自动对反斜杠进行转义。因此,总是将“/”转换成“//”。
这是必须的,因为ActionScript编译器将“//”认为字符“/”,当初始化属性值时会去掉第一个反斜杠。
注意:不要使用反斜杠(/)作为应用目录的路径分隔符。应当总是使用正斜杠(/)作为分隔符。
对于String类型的属性,有两种方式在String中插入换行符:
要使用 代码插入换行符,可以在MXML的属性值中包含该代码,如下所示:
<mx:TextArea width="100%" text="Display Content"/>
要使用ActionScript String变量插入换行符,可以创建一个ActionScript变量,然后使用数据绑定设置MXML中的属性,如下所示:
<mx:Script>
<![CDATA[
[Bindable]
public var myText:String = "Display" + "/n" + "Content";
]]>
</mx:Script>
<mx:TextArea width="100%" text="{myText}"/>
本例中,TextArea控件的text属性值被设置为包含一个换行符。
注意,本例中在属性定义前有[Bindable]元数据标签。元数据标签指定了myText属性可以作为数据绑定表达式的source。运行时当属性变化时数据绑定会自动将一个对象的source属性值复制给另一个对象的destination属性。
如果你省略了元数据标签,编译器会发出警告,指出该属性不能作为数据绑定的source。更多信息,参见绑定数据。
当一个类以数组作为它的属性值时,可以在MXML中使用子标签表示该属性。下面例子中的组件有一个dataProvider属性,包含数字数组:
<mx:List width="150">
<mx:dataProvider>
<mx:Array>
<mx:Number>94062</mx:Number>
<mx:Number>14850</mx:Number>
<mx:Number>53402</mx:Number>
</mx:Array>
</mx:dataProvider>
</mx:List>
数组元素外的<mx:Array>和</mx:Array>标签可选。因此,这个例子代码也可以写成以下所示:
<mx:List width="150">
<mx:dataProvider>
<mx:Number>94062</mx:Number>
<mx:Number>14850</mx:Number>
<mx:Number>53402</mx:Number>
</mx:dataProvider>
</mx:List>
本例中,因为dataProvider属性的数据类型定义为数组,因此Flex会自动将三个数字定义转换为一个三元素数组。
组件开发人员可能在定义数组元素数据类型的组件定义内已经指定了一些其他信息。比如,如果开发人员指定dataProvider属性只支持String元素,那么这个例子会报编译错误,因为你指定了数字。《Adobe Flex Language Reference》描述了用来定义数组元素要求数据类型的Array属性。
当组件以对象作为属性值时,可以在MXML中用含标签属性的子标签表示该属性:
<mynamespace:MyComponent>
<mynamespace:nameOfProperty>
<mynamespace:typeOfObject prop1="val1" prop2="val2"/>
</mynamespace:nameOfProperty>
</mynamespace:MyComponent>
下面的例子给出了一个定义Address对象的ActionScript类。该对象在下一个示例中作为PurchaseOrder组件的属性。
class Address
{
public var name:String;
public var street:String;
public var city:String;
public var state:String;
public var zip:Number;
}
以下示例给出了一个ActionScript类,定义了一个含Address类型属性的PurchaseOrder组件:
import example.Address;
class PurchaseOrder {
public var shippingAddress:Address;
public var quantity:Number;
...
}
MXML中定义了PurchaseOrder组件,如下所示:
<mynamespace:PurchaseOrder quantity="3" xmlns:e="example">
<mynamespace:shippingAddress>
<mynamespace:Address name="Fred" street="123 Elm St."/>
</mynamespace:shippingAddress>
</mynamespace:PurchaseOrder>
如果shippingAddress属性值是Address的子类(比如DomesticAddress),你可以声明该属性值,如下所示:
<mynamespace:PurchaseOrder quantity="3" xmlns:e="example">
<mynamespace:shippingAddress>
<mynamespace:DomesticAddress name="Fred" street="123 Elm St."/>
</mynamespace:shippingAddress>
</mynamespace:PurchaseOrder>
如果该属性被显式设置为Object类型,如同下面例子中value属性,可以使用<mx:Object>标签指定一个匿名对象。
class ObjectHolder {
public var value:Object
}
下面的例子给出了如何指定一个匿名对象作为value属性的值:
<mynamespace:ObjectHolder>
<mynamespace:value>
<mx:Object foo='bar'/>
</mynamespace:value>
</mynamespace:ObjectHolder>
当组件有一个以数组作为值的Object类型的属性,在MXML中可以使用子标签表示该属性,如下所示:
<mynamespace:MyComponent>
<mynamespace:nameOfObjectProperty>
<mx:Array>
<mx:Number>94062</mx:Number>
<mx:Number>14850</mx:Number>
<mx:Number>53402</mx:Number>
</mx:Array>
</mynamespace:nameOfObjectProperty>
</mynamespace:MyComponent>
本例中,你初始化该Object为三元素的数字数组。
正如设置标量值数组中所述,Array元素外的<mx:Array>和</mx:Array>标签可选,可以被省略,如下所示:
<mynamespace:MyComponent>
<mynamespace:nameOfObjectProperty>
<mx:Number>94062</mx:Number>
<mx:Number>14850</mx:Number>
<mx:Number>53402</mx:Number>
</mynamespace:nameOfObjectProperty>
</mynamespace:MyComponent>
这项规则的唯一例外是在你指定Object属性为单个数组元素时。这种情况下,Flex不会创建包含单个元素数组的Object,而是创建一个对象,设置它为指定值。以下是二者区别:
object=[element] // 包含单元素数组的Object
object=element // 等于值的object
如果你想创建单元素数组,在数组元素外包含<mx:Array>和</mx:Array>标签,如下所示:
<mynamespace:MyComponent>
<mynamespace:nameOfObjectProperty>
<mx:Array>
<mx:Number>94062</mx:Number>
</mx:Array>
</mynamespace:nameOfObjectProperty>
</mynamespace:MyComponent>
当组件以对象数组作为属性值时,可以在MXML中使用子标签表示属性,如下所示:
<mynamespace:MyComponent>
<mynamespace:nameOfProperty>
<mx:Array>
<mynamespace:objectType prop1="val1" prop2="val2"/>
<mynamespace:objectType prop1="val1" prop2="val2"/>
<mynamespace:objectType prop1="val1" prop2="val2"/>
</mx:Array>
</mynamespace:nameOfProperty>
</mynamespace:MyComponent>
下面例子中的组件包含ListItem对象数组。每一个ListItem对象有label和data属性。
<mynamespace:MyComponent>
<mynamespace:dataProvider>
<mx:Array>
<mynamespace:ListItem label="One" data="1"/>
<mynamespace:ListItem label="Two" data="2"/>
</mx:Array>
</mynamespace:dataProvider>
</mynamespace:MyComponent>
下面的例子给出了如何指定匿名对象作为dataProvider属性值:
<mynamespace:MyComponent>
<mynamespace:dataProvider>
<mx:Array>
<mx:Object label="One" data="1"/>
<mx:Object label="Two" data="2"/>
</mx:Array>
</mynamespace:dataProvider>
</mynamespace:MyComponent>
正如设置标量值数组章节所述,数组元素外的<mx:Array>和</mx:Array>标签可选,可以省略,如下所示:
<mynamespace:MyComponent>
<mynamespace:dataProvider>
<mx:Object label="One" data="1"/>
<mx:Object label="Two" data="2"/>
</mynamespace:dataProvider>
</mynamespace:MyComponent>
如果一个组件包含了XML数据属性,该属性值就是可以应用命名空间的XML片段。在下面的例子中,MyComponent对象的value值是XML数据:
<mynamespace:MyComponent>
<mynamespace:value xmlns:a="http://www.example.com/myschema">
<mx:XML>
<a:purchaseorder>
<a:billingaddress>
...
</a:billingaddress>
...
</a:purchaseorder>
</mx:XML>
</mynamespace:value>
</mynamespace:MyComponent>
MXML标签中的样式或效果属性和其他属性不同,因为它对应于ActionScript样式或效果,而不是ActionScript类的属性。在ActionScript使用setStyle(stylename, value)方法设置这些属性,而不是object.property=value。
在ActionScript类中使用[Style]或[Effect]元数据标签定义样式或效果属性,而不是定义为ActionScript变量或setter/getter方法。更多信息,参见《Creating and Extending Adobe Flex 3 Components》中的自定义组件中的元数据标签。
比如,在MXML设置fontFamily样式属性,如下所示:
<mx:TextArea id="myText" text="hello world" fontFamily="Tahoma"/>
该 MXML 代码等价于以下ActionScript 代码:
myText.setStyle("fontFamily", "Tahoma");
MXML标签的事件属性允许你指定事件的事件监听器。该属性相当于在ActionScript中使用addEventListener()方法设置事件监听器。
在ActionScript类中使用[Event]元数据标签定义事件属性,而不是定义为ActionScript变量或setter/getter方法。更多信息,参见《Creating and Extending Adobe Flex 3 Components》中的子定义组件中的元数据标签
比如,你可以在MXML中设置creationComplete事件属性,代码如下所示:
<mx:TextArea id="myText" creationComplete="creationCompleteHandler()"/>
该 MXML 代码等价于以下ActionScript 代码:
myText.addEventListener("creationComplete", creationCompleteHandler);
某些MXML标签,比如<mx:Script>标签,有以外部文件URL为值的属性。比如,可以在<mx:Script>标签中设置source属性引用外部ActionScript文件,代替在<mx:Script>标签体内直接键入ActionScript。
注意:在<mx:Script>标签的source属性指定脚本。不要在source属性中指定ActionScript类。关于使用ActionScript类的更多信息,参见创建ActionScript组件。
MXML 支持以下URL类型:
<mx:Style source="http://www.somesite.com/mystyles.css">
<mx:HTTPService url="@ContextRoot()/directory/myfile.xml"/>
<mx:Script source="/myscript.as"/>
<mx:Script source="../myscript.as"/>
对于RegExp类型的属性,你可以在MXML中使用以下格式定义值:
"/pattern/flags"
pattern 在两条斜线内指定正则表达式。两条斜线均必需。
flags(可选) 指定正则表达式的任意标记。
比如,MXML组件的regExpression属性为RegExp类型。因此,可以如下设置它的值:
<mynamespace:MyComponent regExpression="//Wcat/gi"/>
或者使用子标签设置,如下所示:
<mynamespace:MyComponent>
<mynamespace:regExpression>//Wcat/gi</mynamespace:regExpression>
</mynamespace:MyComponent>
正则表达式的flags部分可选,因此还可以如下指定:
<mynamespace:MyComponent regExpression="//Wcat/"/>
编译器标签是一些不直接对应于ActionScript对象或属性的标签。下列编译器标签的命名第一个字母大写:
下列编译器标签全是小写字母:
MXML 有以下语法要求: