在創建組件時,MXML和ActionScript語言有不同的優點和缺點。
- 當你創建一個創建一個符合組件,MXML使得它容易被創建和安置子組件。
- 當你修改組件的行爲,也就是說,覆蓋他的方法,那麼應該使用ActionScript。
大多數時間,當創建組件和應用時,同時使用MXML和ActionScript。Flex提供幾種同時使用MXML和ActionScript的途徑,包含如下:
- 在MXML標記中放置ActionScript代碼聲明,這使用於內聯事件處理
- 在<mx:Script>標記中放置ActionScript代碼。
- 使用<mx:Script>標記的source屬性引入外部ActionScript文件。
- 使用MXML安置組件,把ActionScript代碼放在一個類定義中。這種方式被叫做代碼分離
要代碼behind使用連接ActionScript和MXML,需要讓ActionScript類作爲MXML組件的更標記。也就是說,MXML組件擴展ActionScript類。
例如,要實現自定義AddressForm組件(顯示符合地址登記表),你需要做如下事情:
1. 創建一個叫做AddressFormClass的ActionScript類。你可以使這個類擴展基本的Flex類。既然這樣,使用Form容器的佈局能力並且使AddressFormClass擴展mx.contain.form 類。
2. 創建一個命名爲AddressForm的MXML組件,並且事他的更標記是AddressFormClass。
3. 使用MXML佈局AddressForm組件的內容
4. 使用ActionScript來創建AddressForm組件的邏輯。
提示:你必須聲明子組件爲公共屬性,在ActionScript類中
在下邊的例子包含了自定義的AddressForm組件。主程序文件也利用了代碼behind,並且這個例子也包含CountryCombox和PaddedPanel組件,這些在其他指導中創建的組件。
連接:在構建Flex應用程序時,這被認爲是最佳實踐架構的引論。更多的信息,查看Arp framework——一個開源的模式基礎框架,用來創建Flash和Flex應用程序,他使用了代碼分離。
例子
components/AddressFormClass.as
package components
{
import mx.events.FlexEvent;
import mx.controls.Button;
import mx.controls.TextInput;
import Flash.events.MouseEvent;
import mx.containers.Form;
public class AddressFormClass extends Form
{// Components in the MXML must be
// declared public. This is a limitation in
// the current version of Flex and may change
// in the future.
public var submitButton:Button;
public var nameInput:TextInput;
public var street:TextInput;
public var city:TextInput;
public var state:TextInput;
public var country:CountryComboBox;
// Constructorpublic function AddressFormClass ():void
{
addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
}
// Creation complete is a good time to add event listeners and
// interact with child components.
private function creationCompleteHandler (event:FlexEvent):void{
submitButton.addEventListener(MouseEvent.CLICK, submitHandler);
}
// Gets called when the Submit button is clicked
private function submitHandler (event:MouseEvent):void{
// Gather the data for this form
var addressVO:AddressVO = new AddressVO();
addressVO.name = nameInput.text;
addressVO.street = street.text;
addressVO.city = city.text;
addressVO.state = state.text;
addressVO.country = country.selectedItem as String;
var submitEvent:AddressFormEvent = new AddressFormEvent(AddressFormEvent.SUBMIT);
submitEvent.data = addressVO;
// Dispatch an event to signal that the form has been submitteddispatchEvent(submitEvent);
}
}
}
components/AddressForm.mxml
<?xml version="1.0" encoding="utf-8"?>
<custom:AddressFormClass
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:custom="components.*">
<mx:FormItem label="Name">
<mx:TextInput id="nameInput"/>
</mx:FormItem><mx:FormItem label="Street">
<mx:TextInput id="street"/>
</mx:FormItem><mx:FormItem label="City">
<mx:TextInput id="city"/>
</mx:FormItem><mx:FormItem label="State/County">
<mx:TextInput id="state"/>
</mx:FormItem><mx:FormItem label="Country">
<custom:CountryComboBox id="country"/></mx:FormItem>
<mx:Button
id="submitButton"
label="Submit"
/>
</custom:AddressFormClass>
components/AddressFormEvent.as
package components
{
import Flash.events.Event;
import components.AddressVO;
public class AddressFormEvent extends Event{
public static const SUBMIT:String = "submit";
private var _data:AddressVO;
public function AddressFormEvent (eventName:String)
{super (eventName);
}
public function set data (value:AddressVO):void
{_data = value;
}
public function get data ():AddressVO
{
return _data;}
}
}
components/AddressVO.as
package components{
public class AddressVO
{
// We are using public properties for the
// value object to keep this example short. In a
// real-world application, make these properties// private and use implicit accessors to expose them
// so you can do validation, etc. if necessary.
public var name:String;
public var street:String;
public var city:String;
public var state:String;
public var country:String;
}
}
components/PaddedPanel.as
package components{
import mx.containers.Panel;
public class PaddedPanel extends Panel{
public function PaddedPanel(){
// Call the constructor of the superclass.
super();
// Give the panel a uniform 10-pixel
// padding on all four sides.setStyle ("paddingLeft", 10);
setStyle ("paddingRight", 10);
setStyle ("paddingTop", 10);
setStyle ("paddingBottom", 10);
}
}}
components/CountryComboBox.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml"><mx:dataProvider>
<mx:String>United States</mx:String>
<mx:String>United Kingdom</mx:String>
<!-- Add all other countries. --></mx:dataProvider>
</mx:ComboBox>
components/ApplicationClass.as
package components{
import mx.core.Application;
import mx.events.FlexEvent;
import mx.controls.Alert;
import components.AddressFormEvent;
import components.AddressVO;
import Flash.utils.describeType;
public class ApplicationClass extends Application
{
// Components in MXMLpublic var addressForm:AddressForm;
public function ApplicationClass()
{addEventListener (FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
}
//
// Event handlers
//
private function creationCompleteHandler(event:FlexEvent):void{
// The custom AddressForm component dispatches a "submit"// event the form is submitted. Listen for this.
addressForm.addEventListener(AddressFormEvent.SUBMIT, submitHandler);
}
private function submitHandler(event:AddressFormEvent):void
{// Get the value object (data) from the event object
var data:AddressVO = event.data as AddressVO;
// Compose a string to display the contents of the value object to the user.
var msg:String = "You submitted the following information: /r";
// Use the new introspection API and E4X to get a list of the properties
// in the data object and enumerate over them to compose the string.
var dataProperties:XMLList = describeType(data)..variable;
for each (var i:XML in dataProperties)
{
var propertyName:String = i.@name;msg += i.@name + ": " + data[i.@name] + "/r";
}
// Display the contents of the address form to the user.Alert.show(msg, "Thank you for submitting the form!");
}
}
}
應用程序 MXML 文件
<?xml version="1.0" encoding="utf-8"?>
<custom:ApplicationClass
xmlns:custom="components.*"
viewSourceURL="src/CodeBehind/index.html"width="400" height="310"
>
<custom:PaddedPanel title="Code Behind">
<custom:AddressForm id="addressForm"/></custom:PaddedPanel>
</custom:ApplicationClass>